การเข้าร่วมองค์ประกอบของรายการหากองค์ประกอบเหล่านั้นอยู่ในระหว่างสองช่องว่าง


24

ฉันมีอินพุตเช่นนี้:

['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

ฉันต้องการเข้าร่วมองค์ประกอบระหว่าง''เพื่อให้ได้ผลลัพธ์เช่นนี้

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

ฉันลองใช้joinและแบ่งรายการแบบนี้:

a=['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
a[2:5] = [''.join(a[ 2: 5])]
a=['assembly', '', 'python', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

สิ่งนี้ใช้ได้ในระดับหนึ่ง แต่ฉันไม่รู้วิธีย้ำคำแนะนำนี้สำหรับรายการทั้งหมด

คำตอบ:


27

การใช้itertools.groupby:

from itertools import groupby

l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
new_l = [''.join(g) for k, g in groupby(l, key = bool) if k]

เอาท์พุท:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

2
คำอธิบาย: สิ่งนี้ใช้ "บูล" เพื่อตรวจสอบค่า "Falsey" เช่นสตริงว่างหรือไม่มี
noɥʇʎԀʎzɐɹƆ

7

นี่มันช่างน่ากลัวจริงๆ

lambda b:lambda l:''.join(i or b for i in l).split(b)

สามารถใช้สายใด ๆ ที่คุณสามารถรับประกันไม่ได้อยู่ในการเรียงต่อกันของรายการและกลับฟังก์ชั่นการทำสิ่งที่คุณต้องการ แน่นอนคุณอาจต้องการใช้สิ่งนี้เพียงครั้งเดียวหรือสองครั้งสำหรับสถานการณ์เฉพาะของคุณดังนั้นหากคุณสามารถรับประกันได้ว่าไม่มีองค์ประกอบของรายการที่มีช่องว่างมันอาจมีลักษณะดังนี้:

a = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
a = ''.join(i or ' ' for i in a).split(' ')

4

หากคุณไม่สามารถหรือไม่ต้องการใช้ itertools:

l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
l_new = []
combined = ""
for idx, s in enumerate(l):
    if s != "":
        combined += s
        if idx == len(l)-1:
            l_new.append(combined)

    else:
        l_new.append(combined)
        combined = ""

3

คุณสามารถทำได้:

a = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
indx = ['' == k for k in a]
indx = [i for i, x in enumerate(indx) if x] # get the indices.
a_merged = a[0:indx[0]] + [''.join(a[indx[i]:indx[i+1]]) for i in range(len(indx)) if i < len(indx)-1] + a[indx[-1]+1:] # merge the list

เอาท์พุท:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

แก้ไขหลังจากความคิดเห็น:

a = ['assembly', '','',  'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
indx = [i for i, x in enumerate(a) if x == ''] # get the indices where '' occurs in the original list. 
a_merged = a[0:indx[0]] + [''.join(a[indx[i]:indx[i+1]]) for i in range(len(indx)) if i < len(indx)-1 and indx[i+1] -indx[i] > 1] + a[indx[-1]+1:]
a_merged

เอาท์พุท:

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

# get the indices.ไม่ใช่ความคิดเห็นที่มีประโยชน์มาก ฉันขอแนะนำให้คุณทำให้เป็นประโยชน์ (เช่นfilter the indices to keep only those that correspond to whitespace) หรือลบออกทั้งหมด
Alexander - Reinstate Monica

อีกทั้งกระบวนการ 2 ขั้นตอนนั้นไม่สามารถทำให้ง่ายขึ้นได้indices = [i for s in a if s == '']หรือ
Alexander - Reinstate Monica

@Alexander ฉันคิดว่าคำแนะนำของคุณสำหรับบรรทัดที่ 2 จะเป็นข้อผิดพลาดทางไวยากรณ์ สามารถลบบรรทัดที่ 2 ได้ถ้าคุณเพิ่ม "เท่ากับสตริงว่าง" ตรวจสอบบรรทัดที่สามเช่นindx = [i for i, x in enumerate(a) if x == '']
Reimus Klinsman

น่าเสียดายที่คำตอบนี้ไม่ได้คำนึงถึงองค์ประกอบแรกหรือสุดท้ายเป็นสิ่งที่ควรเข้าร่วม กด Like a = ['asse','mbly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c+', '+']แต่ดูเหมือนว่าคุณสามารถปรับปรุงบรรทัดที่ 3 ของคุณได้โดยการเพิ่มรายการด้วยสตริง null ที่ส่วนท้ายของการenumerate([''] + a + [''])ลบแล้วa[0:indx[0]]และa[indx[-1]+1:]บนบรรทัดที่ 4 ของคุณซึ่งยังไม่ได้รับการพิจารณาหากมีสองสตริง null ถัดจากแต่ละรายการ แม้ว่า
Reimus Klinsman

1
ขอบคุณ @KeiNagase สำหรับความคิดเห็นที่ดี ดูการแก้ไข
ไร้เดียงสา

2

หากตัวคั่นอินพุตเป็นสตริงว่างเปล่าจริง ๆ คุณสามารถทำได้

strlist = [x or ' ' for x in a]
joined = ''.join(strlist).split()
joined
['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

ขออภัยไม่เห็นคำตอบของ String ที่ไม่เกี่ยวข้อง หากคุณแยก () โดยไม่มีพารามิเตอร์มันจะยุบช่องว่างทั้งหมดซึ่งมีประสิทธิภาพมากกว่าเล็กน้อย
realgeek

1

ค่อนข้างเก่า แต่ก็มีประโยชน์:

from itertools import groupby

lst = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

new_lst = [''.join(values)
           for key, values in groupby(lst, key = lambda x: x == '')
           if not key]
print(new_lst)

อัตราผลตอบแทนนี้

['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']

1

เรียกใช้วนรอบรายการ
ภายในวงผนวกองค์ประกอบเข้ากับสตริงว่างชั่วคราวและตรวจสอบเงื่อนไขว่าองค์ประกอบเป็นสตริงว่างหรือองค์ประกอบสุดท้ายของรายการถ้าเป็นจริงแล้วผนวกตัวแปรชั่วคราวเพื่อรายการออกและเปลี่ยนค่า ของตัวแปรนั้นเป็นสตริงว่างเปล่า
Code:

x=['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
temp=''
output=[]
for y in x:
    temp=temp+y
    if y=='' or y==x[-1]:
        output.append(temp)
        temp=''

print(output)

เอาท์พุท: ['assembly', 'python', 'java', 'ruby', 'javascript', 'c++']


1

ฉันยอมรับว่าคำตอบของคริสใช้วิธีไพ ธ อนส่วนใหญ่แต่มันจะเป็นการดีถ้าปรับคริสตอบคำถามเล็กน้อย แทนที่จะใช้groupby(l,key = bool)เพื่อใช้groupby(l, key = lambda x: x !='')และกำจัดความคลุมเครือที่ไม่จำเป็น

from itertools import groupby

separator = ''
l = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']
new_l = [''.join(g) for k, g in groupby(l, key = lambda x: x !=separator) if k]

ตามที่ระบุไว้ในThe Zen of Python : Explicit ดีกว่าโดยนัย

ป.ล.ฉันแค่เขียนคำตอบใหม่เพราะฉันไม่มีชื่อเสียงพอที่จะเขียนความคิดเห็นเกี่ยวกับคำตอบของคริส


1

อีกรุ่นที่ใช้งานได้ซึ่งมีการทดสอบลูปพื้นฐานเท่านั้น:

txt = ['assembly', '', 'py', 'tho', 'n', '', 'ja', 'va', '', 'rub', 'y', '', 'java', 'script', '', 'c++']

out = []
temp = ''

for s in txt:
   if s == '':
      if temp != '':
         out.append(temp) 
         temp = ''
      out.append('')
   else:
      temp = temp + s

if temp != '':
   out.append(temp)

out
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.