如何在保留一些嵌套的同时展平列表(在python中)

2024-10-03 11:15:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带有字符串的列表列表,类似于这样(表示文本的章节、段落和句子)):

[ [[ ['chp1p1s1'], ['chp1p1s2'], ['chp1p1s3'] ],
   [ ['chp1p2s1'], ['chp1p2s2'], ['chp1p2s3'] ]],
  [[ ['chp2p1s1'], ['chp2p1s2'], ['chp2p1s3'] ],
   [ ['chp2p2s1'], ['chp2p2s2'], ['chp2p2s3'] ]] ]

我知道如何将此列表完全展平(例如通过[x for y in z for x in y]),但我想做的是将其部分展平,最终如下所示:

[ [ ['chp1p1s1'], ['chp1p1s2'], ['chp1p1s3'],
    ['chp1p2s1'], ['chp1p2s2'], ['chp1p2s3'] ],
  [ ['chp2p1s1'], ['chp2p1s2'], ['chp2p1s3'],
    ['chp2p2s1'], ['chp2p2s2'], ['chp2p2s3'] ] ]

我通过一些for循环解决了这个问题:

semiflattend_list=list()
for chapter in chapters:
    senlist=list()
    for paragraph in chapter:
        for sentences in paragraph:
            senlist.append(sentences)
    semiflattend_list.append(senlist)

但我想知道有没有更好、更短的解决方案?(我不认为zip是一种方式,因为我的列表大小不同。)


Tags: in列表forlistsenlistchp1p2s3chp1p1s2chp2p2s1
1条回答
网友
1楼 · 发布于 2024-10-03 11:15:09

我能看到的最简单的变化是使用itertools.chain方法:

q = [
     [[ ['chp1p1s1'], ['chp1p1s2'], ['chp1p1s3'] ],
       [ ['chp1p2s1'], ['chp1p2s2'], ['chp1p2s3'] ]],
     [[ ['chp2p1s1'], ['chp2p1s2'], ['chp2p1s3'] ],
       [ ['chp2p2s1'], ['chp2p2s2'], ['chp2p2s3'] ]]
    ]

r = [list(itertools.chain(*g)) for g in q]
print(r)

[[['chp1p1s1'], ['chp1p1s2'], ['chp1p1s3'], ['chp1p2s1'], ['chp1p2s2'], ['chp1p2s3']],
 [['chp2p1s1'], ['chp2p1s2'], ['chp2p1s3'], ['chp2p2s1'], ['chp2p2s2'], ['chp2p2s3']]]

那么,[list(itertools.chain(*g)) for g in q]是什么意思:

# If I only had this
[g for g in q]
# I would get the same I started with.
# What I really want is to expand the nested lists

# * before an iterable (basically) converts the iterable into its parts.
func foo(bar, baz):
   print( bar + " " + baz )

lst = ["cat", "dog"]
foo(*lst) # prints "cat dog"

# itertools.chain accepts an arbitrary number of lists, and then outputs 
# a generator of the results:
c = itertools.chain([1],[2])
# c is now <itertools.chain object at 0x10e1fce10>
# You don't want an generator though, you want a list. Calling `list` converts that:
o = list( c )
# o is now [1,2]
# Now, together:
myList = [[2],[3]]
flattened = list(itertools.chain(*myList))
# flattened is now [2,3]

相关问题 更多 >