有没有更简单的方法在字典值上运行函数而不失去键的关联?
我想对字典里的所有值运行一个函数。不过事情有点复杂,因为每个值的变化并不是独立的,而是要依赖于之前其他值的变化。
这里有一个简单的函数,定义在一个列表上,来说明我的意思:
def new_list_generator(mylist):
number_of_iterations = 0
new_list = []
for n in mylist:
if number_of_iterations%2 == 0:
new_list.append(n**1.25)
number_of_iterations += 1
else:
new_list.append(n**0.5)
number_of_iterations += 1
return new_list
你可以看到,我们对每个值的处理是依赖于历史的,也就是在它之前有多少个值被修改过。
现在,这个函数是针对列表定义的。如果我想修改字典里的值,但又不想把键和值分开(也就是说,我不想简单地把所有值放到一个列表里,然后把这个列表传给函数),那该怎么办呢?
我想到的最好的解决办法(并且能让它工作)是这样一个繁琐的步骤:
第一步:把字典转换成一个元组的列表。也就是像这样:[(value1,key1), (value2,key2),...]
第二步:在这个列表上运行一个修改过的函数。
第三步:用 dict() 把列表再转换回字典。
也就是说:
some_dict = {"Graham": 13, "Eric": 19, "Terry G": 7, "Terry J":11, "John": 15, "Michael": 7}
dict_to_tuples = some_dict.items()
def new_list_generator1(mylist): # notice it's a new function
number_of_iterations = 0
new_list = []
for n in mylist:
if number_of_iterations%2 == 0:
new_list.append((n[0],n[1]**1.25)) # <== new
number_of_iterations += 1
else:
new_list.append((n[0],n[1]**0.5)) # <== new
number_of_iterations += 1
return new_list
tups = new_list_generator1(dict_to_tuples)
print dict(tups)
我在想有没有更简单的方法来做到这一点,希望不需要修改原来的列表。我在网上查了查,发现 Stackoverflow 或其他地方都没有关于这个问题的有用信息(也就是当字典值的处理依赖于历史时)。
谢谢你的帮助。
2 个回答
0
正如评论中提到的,按照字典的遍历顺序来处理值是有点奇怪的,因为这个顺序并不是固定的,所以每次你应用这个函数时,可能会得到不同的结果。不过,如果你在处理时只考虑遍历的步骤,那么你可以简单地使用字典推导式:
{key: some_dict[key]**([1.25, 0.5][i % 2]) for i, key in enumerate(some_dict)}
或者更一般地说
def process_value(value, iteration_step):
# new_value = ...
return new_value
{key: process_value(some_dict[key], i) for i, key in enumerate(some_dict)}
1
只需要遍历这些键,然后直接修改对应的值就可以了。
some_dict = {"Graham": 13, "Eric": 19, "Terry G": 7, "Terry J":11, "John": 15, "Michael": 7}
def new_list_generator1(mydict): # notice it's a new function
number_of_iterations = 0
for key in mydict:
if number_of_iterations%2 == 0:
mydict[key] = mydict[key]**1.25
else:
mydict[key] = mydict[key]**0.5
number_of_iterations += 1
return mydict
print new_list_generator1(some_dict)
正如@kroolik在下面正确指出的,这个过程可以进一步简化,至少在当前这个例子中可以使用enumerate
。
def new_list_generator1(mydict): # notice it's a new function
for i, key in enumerate(mydict):
if i%2 == 0: mydict[key] = mydict[key]**1.25
else: mydict[key] = mydict[key]**0.5
return mydict