通过迭代字典来创建列表

时间:2016-11-11 09:45:08

标签: python list loops dictionary

我定义了这样的字典(list是整数列表):

my_dictionary = {'list_name' : list, 'another_list_name': another_list}

现在,我想通过迭代这个字典来创建一个新列表。最后,我希望它看起来像这样:

my_list = [list_name_list_item1, list_name_list_item2, 
                list_name_list_item3, another_list_name_another_list_item1]

等等。

所以我的问题是:我怎么能意识到这一点?

我试过

for key in my_dictionary.keys():
    k = my_dictionary[key]
    for value in my_dictionary.values():
        v = my_dictionary[value]
        v = str(v)
        my_list.append(k + '_' + v)

但是,在此示例的第4行中,我收到了类型错误(不可用类型:' list')而不是所需的输出。

6 个答案:

答案 0 :(得分:5)

你试图通过它的价值得到字典项,而你已经拥有了你的价值。

使用列表推导在一行中执行:

my_dictionary = {'list_name' : [1,4,5], 'another_list_name': [6,7,8]}

my_list = [k+"_"+str(v) for k,lv in my_dictionary.items() for v in lv]

print(my_list)

结果:

['another_list_name_6', 'another_list_name_7', 'another_list_name_8', 'list_name_1', 'list_name_4', 'list_name_5']

请注意,由于字典中的顺序无法保证,因此列表的顺序也不是。您可以通过按键对项目进行排序来修复订单:

my_list = [k+"_"+str(v) for k,lv in sorted(my_dictionary.items()) for v in lv]

答案 1 :(得分:2)

试试这个:

my_list = []
for key in my_dictionary:
    for item in my_dictionary[key]:
        my_list.append(str(key) + '_' + str(item))

希望这有帮助。

答案 2 :(得分:0)

你已经在键上写了一个外循环,然后在值上面写了一个内循环,并尝试将每个值用作键,这是程序失败的地方。只需使用字典的items方法迭代键值对,即可:

["{}_{}".format(k,v) for k,v in d.items()]

糟糕,无法解析所需的格式;我们要在内部列表中生成每个项目。不用担心...

d={1:[1,2,3],2:[4,5,6]}
list(itertools.chain(*(
      ["{}_{}".format(k,i) for i in l]
      for (k,l) in d.items() )))

这有点复杂。我们再次从字典中获取键值对,然后在列表上创建一个内部循环,将其格式化为字符串。这会生成内部序列,因此我们使用chain和*将其展平,最后将结果保存为一个列表。

编辑:当嵌套为生成器表达式时,Python 3.4.3变得非常混乱;我必须将内部转换为列表,否则在进行格式化之前它将替换k和l的某些组合。

再次编辑:正如有人发布了一个已删除的答案(让我感到困惑),我过于复杂了。你可以用链式理解来进行扁平嵌套:

["{}_{}".format(k,v) for k,l in d.items() for v in l]

这种方法也由Jean-FrançoisFabre发布。

答案 3 :(得分:0)

你当前的问题是dict().values()是一个生成器从字典中产生值,而不是键,所以当你尝试在第4行进行查找时,它会失败(在这种情况下)作为值字典不能用作键。在另一种情况下,例如{1:2, 3:4},它会因KeyError而失败,而{1:2, 2:1}不会引发错误,但可能会造成令人困惑的行为。

至于你的实际问题,列表不会将任何名称归因于数据,就像字典那样;他们只是存储索引。

def f()
    a = 1
    b = 2
    c = 3
    l = [a, b, c]

    return l

调用f()将返回[1, 2, 3],其中abc的任何概念都将完全丢失。

如果您想简单地连接字典中的列表,复制第一个列表,然后在其上调用.extend()即可:

my_list = my_dictionary['list_name'][:]
my_list.extend(my_dictionary['another_list_name'])

如果您希望保留列表的顺序'项目虽然仍然按名称引用,但请查看OrderedDict class in collections

答案 4 :(得分:0)

使用像这样的列表推导

d = {"test1":[1,2,3,],"test2":[4,5,6],"test3":[7,8,9]}

new_list = [str(item[0])+'_'+str(v) for item in d.items() for v in item[1]]

输出:

new_list:
['test1_1',
 'test1_2',
 'test1_3',
 'test3_7',
 'test3_8',
 'test3_9',
 'test2_4',
 'test2_5',
 'test2_6']

答案 5 :(得分:0)

让我们初始化我们的数据

In [1]: l0 = [1, 2, 3, 4]

In [2]: l1 = [10, 20, 30, 40]

In [3]: d = {'name0': l0, 'name1': l1}

请注意,在我的示例中,与您的不同,列表的内容不是字符串...不是列出异构容器吗?

也就是说,你不能简单地加入密钥和列表的项目,你最好使用str(...)内置函数将这些值转换为字符串。

现在它解决了你的问题...我使用列表理解 有两个循环,外循环首先出现在字典中的项目(即键值对),内循环到第二个,它在相应列表中的项目上。

In [4]: res = ['_'.join((str(k), str(i))) for k, l in d.items() for i in l]

In [5]: print(res)
['name0_1', 'name0_2', 'name0_3', 'name0_4', 'name1_10', 'name1_20', 'name1_30', 'name1_40']

In [6]: 

在您的情况下,使用str(k)+'_'+str(i)也可以,但使用固定'text'加入字符串的当前惯用法是'text'.join(...)方法。请注意.join采用SINGLE参数,可迭代,因此在我使用join((..., ...))的列表推导中 在单个参数中收集joinands。