목록의 내용을 가져 와서 다른 목록에 추가


193

목록의 내용을 가져 와서 다른 목록에 추가하는 것이 합리적인지 이해하려고합니다.

루프 함수를 통해 생성 된 첫 번째 목록이 있는데, 파일에서 특정 줄을 가져 와서 목록에 저장합니다.

그런 다음 두 번째 목록을 사용하여 이러한 줄을 저장하고 다른 파일에서 새주기를 시작합니다.

내 생각은 한 번주기가 완료되면 목록을 가져와 두 번째 목록으로 덤프 한 다음 새주기를 시작하고 첫 번째 목록의 내용을 두 번째 목록으로 다시 덤프하지만 추가하면 두 번째 목록이됩니다. 내 루프에서 작성된 모든 작은 목록 파일의 합. 특정 조건이 충족되는 경우에만 목록을 추가해야합니다.

다음과 비슷한 모양입니다.

# This is done for each log in my directory, i have a loop running
for logs in mydir:

    for line in mylog:
        #...if the conditions are met
        list1.append(line)

    for item in list1:
        if "string" in item: #if somewhere in the list1 i have a match for a string
            list2.append(list1) # append every line in list1 to list2
            del list1 [:] # delete the content of the list1
            break
        else:
            del list1 [:] # delete the list content and start all over

이것이 의미가 있거나 다른 경로로 가야합니까?

로그 목록이 길고 각 텍스트 파일이 상당히 크기 때문에 너무 많은주기를 거치지 않는 효율적인 것이 필요합니다. 그래서 목록이 목적에 맞을 것이라고 생각했습니다.

답변:


371

당신은 아마 원한다

list2.extend(list1)

대신에

list2.append(list1)

차이점은 다음과 같습니다.

>>> a = range(5)
>>> b = range(3)
>>> c = range(2)
>>> b.append(a)
>>> b
[0, 1, 2, [0, 1, 2, 3, 4]]
>>> c.extend(a)
>>> c
[0, 1, 0, 1, 2, 3, 4]

list.extend()임의의 iterable을 허용 하므로 대체 할 수도 있습니다

for line in mylog:
    list1.append(line)

으로

list1.extend(mylog)

예, 추가는 한 요소에 해당하며 확장은 concat과 같습니다.
Catalina Chircu

13

작은 목록을 복사하지 않고 여러 개의 작은 목록을 하나의 큰 목록으로 (또는 최소한 하나의 큰 반복 가능한 것으로) 처리하는 빠른 방법 은 itertools.chain 을 살펴보십시오 .

>>> import itertools
>>> p = ['a', 'b', 'c']
>>> q = ['d', 'e', 'f']
>>> r = ['g', 'h', 'i']
>>> for x in itertools.chain(p, q, r):
        print x.upper()

정말 매끄럽게 들립니다! itertools를 이미 사용하고있는 코드를 바꿀 수 있는지 확인하기 위해 살펴볼 것입니다!
user1006198

3

당신이하려는 일에 상당히 합리적입니다.

파이썬에서 많은 노력을 기울이는 약간 짧은 버전은 다음과 같습니다.

for logs in mydir:

    for line in mylog:
        #...if the conditions are met
        list1.append(line)

    if any(True for line in list1 if "string" in line):
        list2.extend(list1)
    del list1

    ....

(True for line in list1 if "string" in line)을 반복 list하고 방출한다 True일치가 발견 될 때마다. any()단락 평가를 사용 True하여 첫 번째 True요소가 발견 되는 즉시 반환 합니다. 끝에 list2.extend()내용을 추가합니다 list1.


1
any(True for line in list1 if "string" in line)보다 깔끔하게 작성됩니다 any("string" in line for line in list1).
Karl Knechtel

좋은 점, @KarlKnechtel은 미묘하게 다르지만. 버전은 항상 True 또는 False를 방출 합니다 . 광산은 하나의 True 만 방출합니다. 나는 그것들이 어떻게 벤치마킹되는지, 또는 중요한 차이가 있는지 전혀 모른다.
Kirk Strauser

두 경우 모두 any발전기를 받는다. True 또는 False 값 목록은 어디에도 구성되지 않습니다. 내 버전은 any확인 하기 위해 더 많은 것을 반환 하지만 생성기 자체에서 동일한 확인을 수행하지 않은 것으로 반환합니다. 나는 그것이 씻기는 것을 상상하지만 timeit, 여기가 아니라 권위가 있습니다. :)
Karl Knechtel

3

'+'연산자를 사용하여 두 목록 (예 : a, b)을 결합 할 수도 있습니다. 예를 들어

a = [1,2,3,4]
b = [4,5,6,7]
c = a + b

Output:
>>> c
[1, 2, 3, 4, 4, 5, 6, 7]

3

이전 답변을 요약합니다. 당신이 목록이있는 경우 [0,1,2]와 또 다른 일을 [3,4,5]하고가되도록 당신이 그들을 병합 할 [0,1,2,3,4,5], 당신도 사용할 수 있습니다 chaining또는 extending귀하의 요구에 현명하게 사용하는 차이를 알아야한다.

목록 확장

listclasses extend메소드를 사용하면 한 목록에서 다른 목록으로 요소를 복사 할 수 있습니다. 그러나 이로 인해 추가 메모리 사용이 발생하며 대부분의 경우 문제가 없지만 메모리를 효율적으로 사용하려는 경우 문제가 발생할 수 있습니다.

a = [0,1,2]
b = [3,4,5]
a.extend(b)
>>[0,1,2,3,4,5]

여기에 이미지 설명을 입력하십시오

리스트 연결

반대로 itertools.chain많은 목록을 연결하는 iterator데 사용할 수 있으며 목록을 반복하는 데 사용할 수있는 소위 호출이 반환 됩니다. 이것은 요소를 복사하지 않고 다음 목록을 가리 키기 때문에 메모리 효율성이 높습니다.

import itertools
a = [0,1,2]
b = [3,4,5]
c = itertools.chain(a, b)

여기에 이미지 설명을 입력하십시오

첫 번째 iterable에서 요소가 소진 될 때까지 요소를 리턴하는 iterator를 작성하고 모든 iterables가 소진 될 때까지 다음 iterable로 진행하십시오. 연속 시퀀스를 단일 시퀀스로 처리하는 데 사용됩니다.


2

사용 map()reduce()내장 함수

def file_to_list(file):
     #stuff to parse file to a list
     return list

files = [...list of files...]

L = map(file_to_list, files)

flat_L = reduce(lambda x,y:x+y, L)

"루핑을위한"최소한의 우아한 코딩 패턴 :)


0

아래와 같은 목록이 있다면 :

list  = [2,2,3,4]

다른 목록으로 복사하는 두 가지 방법.

1.

x = [list]  # x =[] x.append(list) same 
print("length is {}".format(len(x)))
for i in x:
    print(i)
length is 1
[2, 2, 3, 4]

2.

x = [l for l in list]
print("length is {}".format(len(x)))
for i in x:
    print(i)
length is 4
2
2
3
4
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.