我只是用Python语言写了一些遍历dict
或list
的讨厌代码。我有种感觉,这不是最好的方式。
问题是,为了迭代一个字典,这是一个约定:
for key in dict_object:
dict_object[key] = 1
但是,如果在列表上执行相同的操作,则按键修改对象属性将不起作用:
# Throws an error because the value of key is the property value, not
# the list index:
for key in list_object:
list_object[key] = 1
我解决这个问题的方法是编写这个讨厌的代码:
if isinstance(obj, dict):
for key in obj:
do_loop_contents(obj, key)
elif isinstance(obj, list):
for i in xrange(0, len(obj)):
do_loop_contents(obj, i)
def do_loop_contents(obj, key):
obj[key] = 1
有没有更好的方法来做这件事?
谢谢!
发布于 2012-09-07 21:33:07
我从来不需要这样做,从来没有。但如果我这样做了,我可能会这样做:
seq_iter = x if isinstance(x, dict) else xrange(len(x))
例如,在函数形式中:
>>> def seq_iter(obj):
... return obj if isinstance(obj, dict) else xrange(len(obj))
...
>>> x = [1,2,3]
>>> for i in seq_iter(x):
... x[i] = 99
...
>>> x
[99, 99, 99]
>>>
>>> x = {1: 2, 2:3, 3:4}
>>> for i in seq_iter(x):
... x[i] = 99
...
>>> x
{1: 99, 2: 99, 3: 99}
发布于 2012-09-07 21:41:42
这是正确的方法,但如果出于某种原因,您需要以相同的方式对待这两个对象,则可以创建一个迭代器,它将返回索引/键:
def common_iterable(obj):
if isinstance(obj, dict):
return obj
else:
return (index for index, value in enumerate(obj))
它将按照您想要的方式运行:
>>> d = {'a': 10, 'b': 20}
>>> l = [1,2,3,4]
>>> for index in common_iterable(d):
d[index] = 0
>>> d
{'a': 0, 'b': 0}
>>> for index in common_iterable(l):
l[index] = 0
>>> l
[0, 0, 0, 0]
或者更有效地使用生成器:
def common_iterable(obj):
if isinstance(obj, dict):
for key in obj:
yield key
else:
for index, value in enumerate(obj):
yield index
发布于 2012-09-07 21:40:52
要成为pythonic和ducktype-y,也要遵循“请求宽恕而不是许可”,你可以这样做:
try:
iterator = obj.iteritems()
except AttributeError:
iterator = enumerate(obj)
for reference, value in iterator:
do_loop_contents(obj, reference)
不过,如果您需要的只是键/索引:
try:
references = obj.keys()
except AttributeError:
references = range(len(obj))
for reference in references:
do_loop_contents(obj, reference)
或者作为一个函数:
def reference_and_value_iterator(iterable):
try:
return iterable.iteritems()
except AttributeError:
return enumerate(iterable)
for reference, value in reference_and_value_iterator(obj):
do_loop_contents(obj, reference)
或者仅供参考:
def references(iterable):
try:
return iterable.keys()
except AttributeError:
return range(len(iterable))
for reference in references(obj):
do_loop_contents(obj, reference)
https://stackoverflow.com/questions/12325608
复制相似问题