Lấy nội dung của một danh sách và nối nó vào danh sách khác


191

Tôi đang cố gắng để hiểu nếu nó có ý nghĩa để lấy nội dung của một danh sách và nối nó vào một danh sách khác.

Tôi có danh sách đầu tiên được tạo thông qua hàm lặp, nó sẽ lấy các dòng cụ thể ra khỏi tệp và sẽ lưu chúng trong danh sách.

Sau đó, một danh sách thứ hai được sử dụng để lưu các dòng này và bắt đầu một chu kỳ mới trên một tệp khác.

Ý tưởng của tôi là lấy danh sách một lần khi chu trình đã hoàn thành, chuyển nó vào danh sách thứ hai, sau đó bắt đầu một chu kỳ mới, chuyển nội dung của danh sách thứ nhất một lần nữa vào danh sách thứ hai nhưng nối thêm nó, vì vậy danh sách thứ hai sẽ là tổng của tất cả các tệp danh sách nhỏ hơn được tạo trong vòng lặp của tôi. Danh sách phải được nối thêm nếu đáp ứng một số điều kiện.

Nó trông giống như một cái gì đó tương tự như thế này:

# 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

Điều này có ý nghĩa hay tôi nên đi cho một tuyến đường khác?

Tôi cần một cái gì đó hiệu quả mà sẽ không mất quá nhiều chu kỳ, vì danh sách các bản ghi dài và mỗi tệp văn bản là khá lớn; Vì vậy, tôi nghĩ rằng các danh sách sẽ phù hợp với mục đích.

Câu trả lời:


369

Bạn có thể muốn

list2.extend(list1)

thay vì

list2.append(list1)

Đây là sự khác biệt:

>>> 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()chấp nhận một lần lặp tùy ý, bạn cũng có thể thay thế

for line in mylog:
    list1.append(line)

bởi

list1.extend(mylog)

Có, chắp thêm cho một yếu tố, mở rộng giống như concat.
Catalina Chircu

13

Hãy xem itertools.chain để biết cách nhanh chóng coi nhiều danh sách nhỏ là một danh sách lớn duy nhất (hoặc ít nhất là một lần lặp lớn duy nhất) mà không cần sao chép các danh sách nhỏ hơn:

>>> 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()

Nghe thật lắt léo! Tôi sẽ xem xét nó để xem liệu tôi có thể thay thế mã mà tôi đã sử dụng itertools không!
dùng1006198

3

Điều đó có vẻ khá hợp lý cho những gì bạn đang cố gắng làm.

Một phiên bản ngắn hơn một chút dựa trên Python để thực hiện nhiều thao tác nặng hơn có thể là:

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

    ....

Các (True for line in list1 if "string" in line)lặp trên listvà phát ra Truebất cứ khi nào một trận đấu được tìm thấy. any()sử dụng đánh giá ngắn mạch để trả về Truengay khi Truetìm thấy phần tử đầu tiên . list2.extend()nối các nội dung của list1đến cuối.


1
any(True for line in list1 if "string" in line)được viết gọn gàng hơn như any("string" in line for line in list1).
Karl Knechtel

Điểm hay, @KarlKnechtel, mặc dù chúng khác biệt một cách tinh tế. Phiên bản của bạn luôn phát ra thứ gì đó , Đúng hoặc Sai. Của tôi chỉ phát ra một True duy nhất. Tôi không biết làm thế nào những điểm chuẩn đó, hoặc liệu có đủ sự khác biệt để quan trọng không.
Kirk Strauser

Trong cả hai trường hợp, anynhận được một máy phát điện; không có danh sách các giá trị Đúng hoặc Sai được xây dựng ở bất cứ đâu. Phiên bản của tôi trả lại nhiều thứ hơn anyđể kiểm tra, nhưng bù lại không thực hiện kiểm tra tương tự trong chính trình tạo. Tôi tưởng tượng nó là một rửa, nhưng timeitcó thẩm quyền ở đây, không phải tôi. :)
Karl Knechtel

3

Bạn cũng có thể kết hợp hai danh sách (giả sử a, b) bằng toán tử '+'. Ví dụ,

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

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

3

Để tóm tắt lại các câu trả lời trước. Nếu bạn có một danh sách với [0,1,2]và một danh sách khác với [3,4,5]và bạn muốn hợp nhất chúng, để nó trở thành [0,1,2,3,4,5], bạn có thể sử dụng chaininghoặc extendingnên biết sự khác biệt để sử dụng nó một cách khôn ngoan cho nhu cầu của mình.

Mở rộng danh sách

Sử dụng phương thức listlớp extend, bạn có thể sao chép các phần tử từ danh sách này sang danh sách khác. Tuy nhiên, điều này sẽ gây ra việc sử dụng bộ nhớ thêm, điều này sẽ ổn trong hầu hết các trường hợp, nhưng có thể gây ra vấn đề nếu bạn muốn có hiệu quả bộ nhớ.

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

nhập mô tả hình ảnh ở đây

Xâu chuỗi danh sách

Ngược lại, bạn có thể sử dụng itertools.chainđể nối nhiều danh sách, sẽ trả về cái gọi là iteratorcó thể được sử dụng để lặp lại các danh sách. Đây là bộ nhớ hiệu quả hơn vì nó không sao chép các yếu tố mà chỉ trỏ đến danh sách tiếp theo.

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

nhập mô tả hình ảnh ở đây

Tạo một trình vòng lặp trả về các phần tử từ lần lặp đầu tiên cho đến khi nó hết, sau đó chuyển sang lần lặp tiếp theo, cho đến khi tất cả các lần lặp bị cạn kiệt. Được sử dụng để điều trị các chuỗi liên tiếp như là một chuỗi duy nhất.


2

Sử dụng các chức năng map()và tích reduce()hợp sẵn

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)

Tối thiểu "cho vòng lặp" và mẫu mã thanh lịch :)


0

Nếu chúng tôi có danh sách như dưới đây:

list  = [2,2,3,4]

hai cách để sao chép nó vào một danh sách khác.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.