1

私はそれに慣れていないので、次のpythonコードを理解しようとしています。

import random

howMany = random.randint(0,1000)
stats = {}
for i in range(howMany):
   value = random.randint(0,500)
   stats.setdefault(value,0)
   stats[value]+=1
for item in stats:
   if stats[item] > 1:
       print item

これが私がこれまでに理解したことです。私の質問はその後に続きます。

  1. howMany0 と 1000 の間で生成された乱数を格納します。

  2. stats = {}空の辞書を宣言します

  3. iの値に応じて実行されますhowMany。たとえば、howMany が 2の場合、値がとiで 2 回実行されます。01

  4. value変数は、 0&の間の乱数を格納します。500

  5. わからなかったstats.setdefault(value,0)。たとえば、value変数に値がある場合4、それstats.setdefault(4,0)は何を意味するのでしょうか?

  6. 何をしstats[value]+=1ますか?の展開形stats[value]+=1stats[value] = value + 1?

  7. 次の段落を理解しました。

    for item in stats:
       if stats[item] > 1:
           print item
    

    ディクショナリよりも大きい値が出力されます1statsどこか間違っている場合は修正してください。

4

5 に答える 5

3

5. dict.setdefault(key, default)はこれを行います:

キーが辞書にある場合は、その値を返します。そうでない場合は、デフォルトの値でキーを挿入し、デフォルトを返します。デフォルトのデフォルトはなしです。

そのため、関連付けられた値としてすべてのキーが 0 から始まるようにします。

stats.setdefault(value, 0)

したがって、

if value not in stats:
    stats[value] = 0

6.いいえ。しかし、これらは同等です (良いキャッチ、glglgl):

stats[value] += 1
stats[value] = stats[value] + 1

stats( __iadd__vs. )で 2 つの異なるメソッド呼び出しが発生する__setitem__ため、一部のオブジェクトでは異なりますが、ここでは同等です。この例については、Ashwini の回答の優れたリンクを参照してください。

7.このコードは、2 回以上発生するすべての値を出力します。

Python 2.7+ では、コード サンプルはcollections.Counterクラスを使用してより適切に記述できます。

import random
import collections

howMany = random.randint(0,1000)
stats = collections.Counter(random.randint(0, 500) for i in range(howMany))
for item in stats:
   if stats[item] > 1:
       print item
于 2013-05-08T08:44:44.880 に答える
2

「stats.setdefault(value,0)」がわかりませんでした。たとえば、「値」変数の値が 4 の場合、stats.setdefault(4,0) は何を意味するのでしょうか?

辞書のsetdefault()メソッドは、渡されたキーが一致しない場合に値を返します。 valueは検索対象のキーで、0キーが見つからない場合に設定して返す値です。

例外を回避し、KeyError存在しないキーのデフォルト値を設定するために使用されます。

>>> d = {'a': 1}
>>> d['b']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'b'
>>> d.setdefault('b',2)
2
>>> d
{'a': 1, 'b': 2}

"stats[value]+=1" は何をしますか? stats[value]+=1 の拡張形式は stats[value] = value + 1 ですか?

そうではありませんstats[value] = stats[value] + 1

于 2013-05-08T08:45:09.647 に答える
2

stats.setdefault(value,0)指定されたキーvalueが存在する場合はstatsその値を返し、それ以外の場合は指定された新しいキーを作成し、その値valueを に設定してから00 を返します。

>>> dic = {}
>>> dic.setdefault("foo",5)  #creates a new key "foo" with value 5 and returns 5
5
>>> dic
{'foo': 5}
>>> dic.setdefault("foo",10)  # "foo" is already present then simply return it's value
5

ヘルプdict.setdefault: _

>>> dict.setdefault?
String Form:<method 'setdefault' of 'dict' objects>
Namespace:  Python builtin
Docstring:  D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D

stats[value]+=1 は何をしますか?

stats[value]+=1と同等ですstats[value] = stats[value] +1

オブジェクト+=ごとに動作が異なる場合がありますが、詳細については次を参照してください。

Pythonで「i += x」が「i = i + x」と異なるのはいつですか?

于 2013-05-08T08:44:14.633 に答える
1

stats.setdefault(value,0)のデフォルト値を に設定しstats[value]ます0。つまり、以前に値が関連付けられていない場合にのみ、値0がキーに関連付けられます。value効果は次と同じです。

if not stats.has_key(value):
    stats[value] = 0

これは、最初に表示されたときvalueに の値が0関連付けられることを意味します。stats[value]+=1に展開される次のステップを実行できなかったため、これは重要です。これはstats[value] = stats[value]+1、定義する必要 stats[value]があるためです。この場合、ゼロとして定義されます (これが の最初の出現であるvalue場合、 による.setdefault(value,0))。その後はインクリメントされ、次回stats.setdefault(value,0)はすでに値があるため冗長です。

以下は、何setdefaultがより明白になるはずです:

>>> d = {} #make a dictionary
>>> d.setdefault("key",100) #associate the value 100, with the key "key"
100
>>> d["key"] #see what is associated with "key"
100
>>> d["key"]+=100 #increment by 100
>>> d["key"] #test to see if incrementing worked
200
>>> d["notkey"]+=100 #demo to show what happens if we hadn't done defaultdict


Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    d["notkey"]+=100
KeyError: 'notkey'

>>> d.setdefault("notkey",100) #set a default
100
>>> d["notkey"]+=100
>>> d["notkey"]
200
于 2013-05-08T08:44:25.527 に答える
1

5) ドキュメントから:

setdefault(key[, default])

キーが辞書にある場合は、その値を返します。そうでない場合は、値のキーを挿入し、defaultを返しdefaultます。 defaultデフォルトはNoneです。

6) ほぼ同じstats[value] = stats[value] + 1

オペレーター+=は「その場で」操作を実行し、場合によっては既存のオブジェクトを変更できます。また、これらの演算子は異なるメソッドによって決定されるため、動作が異なる場合が__add__あり__iadd__ます。__iadd__ただし、 methodが明示的にオーバーライドされていない場合、拡張代入は method にフォールバックするため、ほとんどの場合、心配する必要はありません__add__

異なる動作の例:

>>> y = x = [1, 2, 3]
>>> x + [4, 5]   # create *new* list
[1, 2, 3, 4, 5]
>>> y
[1, 2, 3]        # old list is not modified

>>> y = x = [1, 2, 3]
>>> x += [4, 5]  # the operation is performed "in place", new object is not created
>>> y
[1, 2, 3, 4, 5]  # value of list changes
于 2013-05-08T08:45:41.257 に答える