Python创建列表列表,其中第一项的长度为一,第二项的长度为n?

时间:2018-09-17 19:54:21

标签: python list

我在用python创建列表列表时遇到问题。假设我有以下列表:

fruitlist = [('Vendor A', 'Apples'),
('Vendor B', 'Apples'),
('Vendor C', 'Bananas'),
('Vendor A', 'Grapes'),
('Vendor A', 'Bananas'),
('Vendor B', 'Oranges')]

我想要做的是创建这样的列表:[[Vendor A, (Apples, Grapes, Bananas)], [Vendor B, (Apples, Oranges)], [Vendor C, (Bananas)]]

因此基本上是供应商,然后是他们的产品。这是我目前拥有的代码,基本上可以通过,仅列出供应商列表,然后遍历并锁定每个产品,但是,输出并不是我想要的。

vendors = list(set([x[0] for x in fruitlist]))
# this creates a list of just vendors:
output = [[] for x in range (len(vendors))]
#This creates a list with 3 empty lists inside (one for each vendor) where my output will be housed
    for x in range(0,len(vendors)):
        for y in range(0,len(fruitlist)):
            if fruitlist[y][0] == vendors[x]:
                output[x].append(fruitlist[y][1])

输出看起来像这样:

[['Apples', 'Oranges'], ['Apples', 'Grapes', 'Bananas'], ['Bananas']]

因此,现在按供应商细分了输出,并且每个供应商的报价都位于其自己的列表中,但是现在我必须弄清楚如何在其中插入供应商名称,而我不能。如果我在for循环的附加部分中包括供应商名称,

output[x].append((fruitlist[y][0],fruitlist[y][1]))

它为每个水果重复供应商名称。如果我使用insert方法,似乎会创建一个全新的项目,并增加列表的长度。我尝试了一些操作,尝试了谷歌搜索,但是我找不到正确的措词。如果有人能指出我正确的方向,我将非常感激。

任何人都可以解释为什么我查找供应商时会出现以下情况:

 ['Vendor B', 'Vendor A', 'Vendor C']

将“ B”放在“ A”之前吗?在我的原始列表中,A是第一个,集合函数是否随机分配顺序?

3 个答案:

答案 0 :(得分:3)

集合只是元素的集合,没有列表那样的顺序。

我写这本书的方式是创建一个字典,然后,当我们将其转换为列表时,我们可以对其进行排序以匹配输入顺序。

fruitlist = [('Vendor A', 'Apples'),
('Vendor B', 'Apples'),
('Vendor C', 'Bananas'),
('Vendor A', 'Grapes'),
('Vendor A', 'Bananas'),
('Vendor B', 'Oranges')]
vendors = {}
for vendor, fruit in fruitlist:
    vendors.setdefault(vendor, []).append(fruit)
ordered_fruitlist_vendors = [t[0] for t in fruitlist]
vendors_list = [[k, tuple(v)] for k,v in vendors.items()]
vendors_list.sort(key=lambda t: ordered_fruitlist_vendors.index(t[0]))

vendors_list设为:

[['Vendor A', ('Apples', 'Grapes', 'Bananas')], ['Vendor B', ('Apples', 'Oranges')], ['Vendor C', ('Bananas',)]]

但是,我怀疑是否需要将整洁的字典转换为带有元组的笨重的2元素列表。您确定要能够在O(1)时间内使用vendors['Vendor A']从供应商那里获取水果,而不必遍历将是O(n)的列表吗?无论如何,这两种方法现在都是选项!


setdefault的解释。

字典的setdefault方法具有两个参数-键和值。如果该键已经存在于字典中,则返回当前值,否则将使用传递到函数中的值创建键并返回该值。

例如:

>>> d = {1:2}
>>> d.setdefault(1,3)
2
>>> d
{1: 2}
>>> d.setdefault(3,4)
4
>>> d
{1: 2, 3: 4}

因此,使用此方法的一个巧妙技巧是将一个密钥设置为一个空列表([])。然后,如果我们还没有该密钥(在我们的情况下还没有找到供应商),那么将返回一个空列表。否则,我们将获得对该列表的引用,该列表包含了到目前为止我们看到的所有供应商的成果。好处是我们可以将我们的新水果添加到返回的所有内容中,或者为该供应商创建一个新条目并添加新水果,或者如果该供应商已经存在,我们将添加到先前创建的列表。

这意味着我们只需要遍历fruitlist一次,这样解决方案便有效。


使用列表的方法的另一个示例:

>>> d = {}
>>> d.setdefault(1, []).append(2)
>>> d
{1: [2]}
>>> d.setdefault(1, []).append(3)
>>> d.setdefault(1, []).append(4)
>>> d
{1: [2, 3, 4]}
>>> d.setdefault(2, []).append(3)
>>> d.setdefault(2, []).append(3)
>>> d.setdefault(2, []).append(3)
>>> d
{1: [2, 3, 4], 2: [3, 3, 3]}

答案 1 :(得分:1)

你好,没有字典

数据

In [15]: fruitlist = [('Vendor A', 'Apples'),
    ...:              ('Vendor B', 'Apples'),
    ...:              ('Vendor C', 'Bananas'),
    ...:              ('Vendor A', 'Grapes'),
    ...:              ('Vendor A', 'Bananas'),
    ...:              ('Vendor B', 'Oranges')]

输出列表,最初为空

In [16]: output = []

我们将使用Python的for循环的罕见功能,即else子句。如果else主体正常结束,即没有for

,则执行break子句的主体
In [17]: for vendor, fruit in fruitlist:
    ...:     for sublist in output:
    ...:         if sublist[0] == vendor:
    ...:             sublist[1].append(fruit)
    ...:             break
    ...:     else:
    ...:         output.append([vendor, [fruit]])

最终我们检查结果

In [18]: output
Out[18]: 
[['Vendor A', ['Apples', 'Grapes', 'Bananas']],
 ['Vendor B', ['Apples', 'Oranges']],
 ['Vendor C', ['Bananas']]]

我不得不说,原始问题提到了子列表,其中第二个元素是一个元组,而我有一个列表,但是元组是不可变的...

答案 2 :(得分:1)

您可以使用一个简单的for循环和一个dictionary,而无需使其复杂化

fruits = [ 
    ('Vendor A', 'Apples'),
    ('Vendor B', 'Apples'),
    ('Vendor C', 'Bananas'),
    ('Vendor A', 'Grapes'),
    ('Vendor A', 'Bananas'),
    ('Vendor B', 'Oranges')
]

dicta = {}

for vendor, item in fruits:
    if vendor not in dicta:
        dicta[vendor] = [item]
    else:
        dicta[vendor].append(item)

print(dicta)
(xenial)vash@localhost:~/python/stack_overflow$ python3.7 fruits.py
{'Vendor A': ['Apples', 'Grapes', 'Bananas'], 'Vendor B': ['Apples', 'Oranges'], 'Vendor C': ['Bananas']}