14

Python でadictまたは aを反復処理する厄介なコードを書きました。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

これを行うより良い方法はありますか?

ありがとう!

4

6 に答える 6

15

私はこれを行う必要はありませんでした。しかし、もしそうなら、私はおそらく次のようなことをするでしょう:

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-07T21:33:07.420 に答える
6

これは正しい方法ですが、何らかの理由でこれら 2 つのオブジェクトを同じ方法で処理する必要がある場合は、何があってもインデックス/キーを返す iterable を作成できます。

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-07T21:41:41.777 に答える
5

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)
于 2012-09-07T21:40:51.870 に答える
1

変更しようとしているオブジェクトが dict であるかリストであるかに応じて、異なるコードが必要な場合があります。

if type(object)==type([]):
    for key in range(len(object)):
        object[key]=1
elif type(object)==type({}): #use 'else' if you know that object will be a dict if not a list
    for key in object:
        object[key]=1
于 2012-09-08T14:21:48.837 に答える
1
test_list = [2, 3, 4]
for i, entry in enumerate(test_list):
    test_list[i] = entry * 2
print(test_list)  # Gives: [4, 6, 8]

しかし、おそらくリスト内包表記が必要です:

test_list = [2, 3, 4]
test_list = [entry * 2 for entry in test_list]
print(test_list)  # Gives: [4, 6, 8]
于 2012-09-07T22:27:08.373 に答える