source

python 목록 결합

bestscript 2022. 12. 12. 21:14

python 목록 결합

목록 목록을 하나의 목록(또는 반복자)에 결합하기 위한 짧은 구문이 python입니까?

예를 들어 다음과 같은 목록을 가지고 있으며 a, b, c를 반복하고 싶습니다.

x = [["a","b"], ["c"]]

제가 생각할 수 있는 최선의 방법은 다음과 같습니다.

result = []
[ result.extend(el) for el in x] 

for el in result:
  print el
import itertools
a = [['a','b'], ['c']]
print(list(itertools.chain.from_iterable(a)))
x = [["a","b"], ["c"]]

result = sum(x, [])

한 단계만 깊이 파고드는 경우에는 내포된 이해력도 작동합니다.

>>> x = [["a","b"], ["c"]]
>>> [inner
...     for outer in x
...         for inner in outer]
['a', 'b', 'c']

한 줄에 다음과 같이 표시됩니다.

>>> [j for i in x for j in i]
['a', 'b', 'c']
l = []
map(l.extend, list_of_lists)

최단!

이를 평탄화라고 하며, 많은 구현이 이루어지고 있습니다.

이것은 어떻습니까? 단, 1레벨의 딥 네스트에서만 동작합니다.

>>> x = [["a","b"], ["c"]]
>>> for el in sum(x, []):
...     print el
...
a
b
c

이러한 링크에서 가장 완전한 패스트엘리건트 etc 구현은 다음과 같습니다.

def flatten(l, ltypes=(list, tuple)):
    ltype = type(l)
    l = list(l)
    i = 0
    while i < len(l):
        while isinstance(l[i], ltypes):
            if not l[i]:
                l.pop(i)
                i -= 1
                break
            else:
                l[i:i + 1] = l[i]
        i += 1
    return ltype(l)

생성기가 아닌 목록이 필요한 경우list():

from itertools import chain
x = [["a","b"], ["c"]]
y = list(chain(*x))

퍼포먼스 비교:

import itertools
import timeit
big_list = [[0]*1000 for i in range(1000)]
timeit.repeat(lambda: list(itertools.chain.from_iterable(big_list)), number=100)
timeit.repeat(lambda: list(itertools.chain(*big_list)), number=100)
timeit.repeat(lambda: (lambda b: map(b.extend, big_list))([]), number=100)
timeit.repeat(lambda: [el for list_ in big_list for el in list_], number=100)
[100*x for x in timeit.repeat(lambda: sum(big_list, []), number=1)]

제작:

>>> import itertools
>>> import timeit
>>> big_list = [[0]*1000 for i in range(1000)]
>>> timeit.repeat(lambda: list(itertools.chain.from_iterable(big_list)), number=100)
[3.016212113769325, 3.0148865239060227, 3.0126415732791028]
>>> timeit.repeat(lambda: list(itertools.chain(*big_list)), number=100)
[3.019953987082083, 3.528754223385439, 3.02181439266457]
>>> timeit.repeat(lambda: (lambda b: map(b.extend, big_list))([]), number=100)
[1.812084445152557, 1.7702404451095965, 1.7722977998725362]
>>> timeit.repeat(lambda: [el for list_ in big_list for el in list_], number=100)
[5.409658160700605, 5.477502077679354, 5.444318360412744]
>>> [100*x for x in timeit.repeat(lambda: sum(big_list, []), number=1)]
[399.27587954973444, 400.9240571138051, 403.7521153804846]

이것은 Windows XP 32비트의 Python 2.7.1을 사용한 것입니다만, 위의 코멘트의 @temoto는from_iterable보다 빠르다map+extend플랫폼과 입력에 의존합니다.

에서 떨어져 있다sum(big_list, [])

이것은 무한 네스트 요소에 대해 재귀적으로 작동합니다.

def iterFlatten(root):
    if isinstance(root, (list, tuple)):
        for element in root:
            for e in iterFlatten(element):
                yield e
    else:
        yield root

결과:

>> b = [["a", ("b", "c") , "d"]>> 리스트 (iter Flatten (b))
['a', 'b', 'c', 'd']

파티에 늦었지만...

나는 비단뱀이 처음이고 혀가 짧은 배경에서 왔다.제가 생각해낸 것은 다음과 같습니다(lulz의 var name을 확인해 주세요).

def flatten(lst):
    if lst:
        car,*cdr=lst
        if isinstance(car,(list,tuple)):
            if cdr: return flatten(car) + flatten(cdr)
            return flatten(car)
        if cdr: return [car] + flatten(cdr)
        return [car]

효과가 있는 것 같아.테스트:

flatten((1,2,3,(4,5,6,(7,8,(((1,2)))))))

반환:

[1, 2, 3, 4, 5, 6, 7, 8, 1, 2]

당신이 설명하는 것은 목록을 평평하게 만드는 것으로 알려져 있으며, 이 새로운 지식을 통해 구글에서 이에 대한 많은 해결책을 찾을 수 있을 것입니다(내장된 평평하게 만드는 방법은 없습니다).다음 중 하나를 http://www.daniel-lemire.com/blog/archives/2006/05/10/flattening-lists-in-python/에서 소개합니다.

def flatten(x):
    flat = True
    ans = []
    for i in x:
        if ( i.__class__ is list):
            ans = flatten(i)
        else:
            ans.append(i)
    return ans

항상 감소(functools로 권장되지 않음):

>>> x = [ [ 'a', 'b'], ['c'] ]
>>> for el in reduce(lambda a,b: a+b, x, []):
...  print el
...
__main__:1: DeprecationWarning: reduce() not supported in 3.x; use functools.reduce()
a
b
c
>>> import functools
>>> for el in functools.reduce(lambda a,b: a+b, x, []):
...   print el
...
a
b
c
>>>

유감스럽게도 목록 연결을 위한 더하기 연산자는 함수로 사용할 수 없습니다. 또는 가시성을 개선하기 위해 못생긴 람다를 선호한다면 다행입니다.

또는 재귀 연산:

def flatten(input):
    ret = []
    if not isinstance(input, (list, tuple)):
        return [input]
    for i in input:
        if isinstance(i, (list, tuple)):
            ret.extend(flatten(i))
        else:
            ret.append(i)
    return ret

1레벨 플랫의 경우 속도에 신경 쓴다면, 제가 시도한 모든 조건 하에서 이전의 어떤 답변보다 더 빠릅니다.(즉, 결과가 목록으로 필요한 경우).즉석에서 반복하기만 하면 될 경우에는 체인 예가 더 나을 수 있습니다.)최종 크기 목록을 미리 할당하고 슬라이스별로 부품을 복사하는 방식으로 작동합니다(반복기 방식보다 낮은 수준의 블록 복사).

def join(a):
    """Joins a sequence of sequences into a single sequence.  (One-level flattening.)
    E.g., join([(1,2,3), [4, 5], [6, (7, 8, 9), 10]]) = [1,2,3,4,5,6,(7,8,9),10]
    This is very efficient, especially when the subsequences are long.
    """
    n = sum([len(b) for b in a])
    l = [None]*n
    i = 0
    for b in a:
        j = i+len(b)
        l[i:j] = b
        i = j
    return l

주석이 있는 정렬된 시간 목록:

[(0.5391559600830078, 'flatten4b'), # join() above. 
(0.5400412082672119, 'flatten4c'), # Same, with sum(len(b) for b in a) 
(0.5419249534606934, 'flatten4a'), # Similar, using zip() 
(0.7351131439208984, 'flatten1b'), # list(itertools.chain.from_iterable(a)) 
(0.7472689151763916, 'flatten1'), # list(itertools.chain(*a)) 
(1.5468521118164062, 'flatten3'), # [i for j in a for i in j] 
(26.696547985076904, 'flatten2')] # sum(a, [])

안타깝게도 Python은 목록을 정리하는 간단한 방법이 없다.이것을 시험해 보세요.

def flatten(some_list):
    for element in some_list:
        if type(element) in (tuple, list):
            for item in flatten(element):
                yield item
        else:
            yield element

그러면 리스트가 반복적으로 평평해집니다.그 후, 다음과 같이 할 수 있습니다.

result = []
[ result.extend(el) for el in x] 

for el in flatten(result):
      print el

배열의 요소와 그 수를 포함하는 사전을 만들어야 했을 때도 비슷한 문제가 있었습니다.정답은 관련성이 있습니다.왜냐하면 목록을 정리하고 필요한 요소를 얻은 후 그룹화하여 세는 것이기 때문입니다.Python의 맵 함수를 사용하여 요소의 태플을 생성했습니다.배열 위에 카운트와 그룹비가 표시됩니다.groupby는 어레이 요소 자체를 키 펑크로 간주합니다.비교적 새로운 Python 코더로서, Python 코더로서도 이해하기 쉽고, Python 코더이기도 합니다.

코드에 대해 설명하기 전에 먼저 정리해야 했던 데이터의 예를 다음에 제시하겠습니다.

{ "_id" : ObjectId("4fe3a90783157d765d000011"), "status" : [ "opencalais" ],
  "content_length" : 688, "open_calais_extract" : { "entities" : [
  {"type" :"Person","name" : "Iman Samdura","rel_score" : 0.223 }, 
  {"type" : "Company",  "name" : "Associated Press",    "rel_score" : 0.321 },          
  {"type" : "Country",  "name" : "Indonesia",   "rel_score" : 0.321 }, ... ]},
  "title" : "Indonesia Police Arrest Bali Bomb Planner", "time" : "06:42  ET",         
  "filename" : "021121bn.01", "month" : "November", "utctime" : 1037836800,
  "date" : "November 21, 2002", "news_type" : "bn", "day" : "21" }

Mongo의 문의 결과입니다.아래 코드는 이러한 목록들의 집합을 보완합니다.

def flatten_list(items):
  return sorted([entity['name'] for entity in [entities for sublist in  
   [item['open_calais_extract']['entities'] for item in items] 
   for entities in sublist])

먼저 모든 엔티티 컬렉션을 추출하고 각 엔티티 컬렉션에 대해 사전을 반복하여 이름 속성을 추출합니다.

언급URL : https://stackoverflow.com/questions/716477/join-list-of-lists-in-python