基于条件/if else语句来拆分Python列表

3

我想要把一个列表分成两个列表。这是该列表:

L = [3.5, 1, 7, 2, 4.5, 1, 6, 2, 4.8, 2, 3.1, 1, 9, 2]

如果我想根据粗体数字(1或2)将列表拆分,这些数字始终是位置上的偶数(2x),那么在1之前的数字放入一个列表,在2之前的数字放入另一个列表:

l1 = [3.5, 4.5, 3.1] #bold number = 1

l2 = [7, 6, 4.8, 9] #bold number = 2

同时,当有+1个粗体数字时,问题可能会扩展,因此需要分成+1个列表。

我应该如何使用if-else语句来处理列表?


2
请展示您的努力 :) 粘贴您的代码也可以。 - 0Tech
就像0Tech所说的那样,展示一下你目前的进展。但是请澄清一下,这些数字是1和2位置还是标志。 - sten
1
@Roxanne,你的编辑弄乱了L列表中的粗体文本。 - PM 2Ring
@PM2Ring 对不起,下次我会再仔细检查。 - RMS
谢谢你的建议@PM2Ring!我曾经认为只有通过“点赞”才能授权给别人信用,而我没有这个权力。(现在我有了) - key
3个回答

5

可以在第2个循环中使用三元表达式,根据值的不同分派到相关列表中的前一个元素(我采取了一种捷径:如果值为1,则为l1,否则为l2,所以这种方法相对脆弱):

l=[3.5, 1 ,7, 2 ,4.5, 1, 6, 2, 4.8, 2 ,3.1,1, 9, 2]

l1,l2 = [],[]
for i in range(1,len(l),2):
    (l1 if l[i]==1 else l2).append(l[i-1])

print(l1,l2)

产出:

[3.5, 4.5, 3.1] [7, 6, 4.8, 9]

一般情况下:根据最大索引创建一个列表的列表,并在循环中根据索引分配值(l[i]-1 是 0 开始的索引,l[i] 是要插入的值)。

lists = [[] for _ in range(max(l[1::2]))]

for i in range(1,len(l),2):
    lists[l[i]-1].append(l[i-1])

print(lists)

结果:

[[3.5, 4.5, 3.1], [7, 6, 4.8, 9]]

使用itertools.islice而不是玩弄索引,可以使最后一部分更加“pythonic”:

import itertools
for i,v in zip(itertools.islice(l,1,len(l),2),itertools.islice(l,0,len(l),2)):
    lists[i-1].append(v)

5

您可以使用字典来保存新列表,以类别编号作为字典键。我们使用defaultdict来简化在字典中创建列表的过程。

from collections import defaultdict

lst = [3.5, 1 ,7, 2, 4.5, 1, 6, 2, 4.8, 2, 3.1, 1, 9, 2]

# Separate data into different lists based on following number
d = defaultdict(list)
it = iter(lst)
for v, k in zip(it, it):
    d[k].append(v) 

# Display lists
for k in sorted(d.keys()):
    print(k, d[k])

输出

1 [3.5, 4.5, 3.1]
2 [7, 6, 4.8, 9]

这段代码可以处理任意数量的分类。

正如Jean-François Fabre在评论中提到的那样,有一种稍微更高效的方法来按排序顺序打印。

from collections import defaultdict

lst = [3.5, 1 ,7, 2, 4.5, 3, 6, 2, 4.8, 3, 3.1, 1, 9, 2]

# Separate data into different lists based on following number
d = defaultdict(list)
it = iter(lst)
for v, k in zip(it, it):
    d[k].append(v) 

# Display lists
for k, v in sorted(d.items()):
    print(k, v)

输出

1 [3.5, 3.1]
2 [7, 6, 9]
3 [4.5, 4.8]

这个算法的核心是:
it = iter(lst)
for v, k in zip(it, it):

it = iter(lst) 创建了一个列表的迭代器对象。我们将这个迭代器的两个副本传递给 zip

zip 循环中,每次得到的是由每个参数中连续的元素组成的元组。换句话说,如果你使用 zip(a, b, c),你将得到 abc 中相应元素的第一个元素,然后是它们的第二个元素等等。

但是,在这里,我们将两个对 it 迭代器的引用传递给了 zip。因此,当 zip 从这两个 it 中读取下一个元素时,实际上是通过 lst 中的一系列项进行处理。因此,在每个 for 循环中,我们都会从 lst 中得到连续的一对元素。


你最好使用 for k,v in sorted(d.items()): 而不是 for k in sorted(d.keys()): 这样你就不需要在循环中使用 d[k] - Jean-François Fabre
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - PM 2Ring

0

虽然不是最干净的尝试,但这里是您需要的。

>>> L=[3.5, 1 ,7, 2 ,4.5, 1, 6, 2, 4.8, 2 ,3.1,1, 9, 2]
>>> o=zip(L, L[1:])[::2]
>>> o
[(3.5, 1), (7, 2), (4.5, 1), (6, 2), (4.8, 2), (3.1, 1), (9, 2)]
>>> map(lambda x: x[0], filter(lambda x: x[1]%2==0, o))
[7, 6, 4.8, 9]
>>> map(lambda x: x[0], filter(lambda x: x[1]%2!=0, o))
[3.5, 4.5, 3.1]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接