นำเนื้อหาของรายการและผนวกเข้ากับรายการอื่น


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()ยอมรับการทำซ้ำแบบสุ่มคุณจึงสามารถแทนที่ได้

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

ดูเหมือนจะสมเหตุสมผลสำหรับสิ่งที่คุณพยายามทำ

เวอร์ชันที่สั้นกว่าเล็กน้อยซึ่งใช้กับ Python ในการยกของหนักมากขึ้นอาจเป็น:

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)iterates กว่า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 แม้ว่าพวกเขาจะแตกต่างกันเล็กน้อย เวอร์ชันของคุณปล่อยบางสิ่งบางอย่างไม่ว่าจะจริงหรือเท็จ ของฉันส่งเสียงจริงเพียงครั้งเดียว ฉันไม่รู้ว่าเกณฑ์มาตรฐานเหล่านั้นออกมาได้อย่างไรหรือว่ามีความแตกต่างมากพอที่จะมีความสำคัญหรือไม่
Kirk Strauser

ในทั้งสองกรณีanyรับเครื่องกำเนิดไฟฟ้า ไม่มีรายการของค่าจริงหรือเท็จถูกสร้างขึ้นที่ใดก็ได้ รุ่นของฉันจะส่งคืนสิ่งต่าง ๆ มากขึ้นสำหรับ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ควรรู้ความแตกต่างเพื่อใช้อย่างชาญฉลาดสำหรับความต้องการของคุณ

การขยายรายการ

ใช้วิธีการlistเรียน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)

ป้อนคำอธิบายรูปภาพที่นี่

สร้างตัววนซ้ำที่ส่งคืนองค์ประกอบจากตัววนซ้ำแรกจนกว่าจะหมดจากนั้นจึงนำไปสู่การวนซ้ำถัดไปจนกว่าตัววนซ้ำทั้งหมดจะหมด ใช้สำหรับการรักษาลำดับที่ต่อเนื่องกันเป็นลำดับเดียว


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.