我正在处理以下格式的python字典:
y = {
'column_a':[0,1,2],
'column_b':[3,4,5],
'column_c':[5,6,7]
}
其中dict的每个元素代表一个表的一列。因此,每一列必须具有相同数量的元素(等于表中的行数,这是我必须自己计算的值)。
我面临的问题是我需要添加另一列,并用单个值填充它。我目前正在写某种形式的
y['column_d'] = [some_value for i in range(len(y[y.keys()[0]]))]
至少在我看来,这是一个相当讨厌的词。 是否有一些更好/更优雅的方式来实现相同的性能(即不迭代列表本身)?
更具体地说,从字典中获取行数的更好方法是什么? IOW,有没有更好的书写方式:
len(y[y.keys()[0]])
答案 0 :(得分:2)
您只能手动对dict值使用“迭代”一次:
some_value = 1
y['column_d'] = [some_value] * len(next(iter(y.values()))) # python 3
y['column_d'] = [some_value] * len(next(y.itervalues())) # python 2
或将dict_values
强制转换为list
(对于 python3 )并获取第一个元素:
y['column_d'] = [some_value] * len(list(y.values())[0]) # python 3
y['column_d'] = [some_value] * len(y.values()[0]) # python 2
更新。
有关@niCkcAMel答案的一些评论。 @ ChristianReall-Fluharty在评论中注意到,他选择此答案的原因之一是执行速度。我决定使用timeit对其进行测试。
两个答案中都提供3种方法。它们之间的区别在于长度的计算方法。因此,我已经完成了小型测试模块:
y = {
'column_a': [0, 1, 2],
'column_b': [3, 4, 5],
'column_c': [5, 6, 7]
}
some_value = 1
def func(L):
y['column_d'] = [some_value] * L
def function1():
L = len(y[y.keys()[0]]) # -- Python 2
# L = len(y[list(y.keys())[0]]) # -- Python 3
func(L)
def function2():
L = len(next(y.itervalues())) # -- Python 2
# L = len(next(iter(y.values()))) # -- Python 3
func(L)
def function3():
L = len(y.values()[0]) # -- Python 2
# L = len(list(y.values())[0]) # -- Python 3
func(L)
if __name__ == "__main__":
import timeit
print(timeit.timeit("function1()", setup="from __main__ import function1"))
print(timeit.timeit("function2()", setup="from __main__ import function2"))
print(timeit.timeit("function3()", setup="from __main__ import function3"))
所以,让我们启动测试。
2.26870775476 # niCk cAMel (3rd)
2.14519973907 # Olvin Roght 1st (winner)
2.1813173881 # Olvin Roght 2nd (2nd)
2.396988793 # niCk cAMel (3rd)
2.175222899 # Olvin Roght 1st (winner)
2.3292458960000006 # Olvin Roght 2nd (2nd)
结论:两种python版本的最快变体是使用itervalues()
/ iter()
获取迭代器对象,并使用next()
从迭代器获取下一个(第一项)
答案 1 :(得分:1)
是的...我也遇到过那些“讨厌”的词句..这是一个建议。
L = len(y[y.keys()[0]])
y['column_d'] = [some_value] * L
答案 2 :(得分:0)
您可以全面理解整个字典,而不必费心获取元素的大小(假设它与先前的行数不同步):
rowsToAdd = 1
defaultValue = [0] * rowsToAdd
y = { k:v + defaultValue for k,v in y.items() }
这是假定所有列都包含相同的数据类型,并希望使用相同的默认值。
如果每个列的默认值都不同,则可以使用每个列名称的默认值制作一个单独的字典,并在理解中使用它:
defaults = {
'column_a':[0],
'column_b':['abc'],
'column_c':[2.5]
}
rowsToAdd = 1
y = { k:v + defaults[k]*rowsToAdd for k,v in y.items() }
答案 3 :(得分:0)
尝试以下解决方案,使用dict.values
获取第一个键的值的长度,然后将其乘以完成:
y['column_d'] = [some_value] * len(list(y.values)[0])
现在:
print(y)
要使column_d
的值重复正确的次数。