1

2 つの変数 (辞書とリスト) の値を比較したい。辞書にはネストされた構造があるため、すべての項目をループする必要があります。簡単な解決策を発見しましたが、これをより良い方法で(Pythonを使用して)実行できると確信しています。簡単に言えば、変数user_from_databaseに存在しないアイテムを見つけたいと思います。user_from_client

私の解決策:

#variable containing users from client side
users_from_client = {
  "0": {
    "COL1": "whatever",
    "COL2": "val1",
    "COL3": "whatever",
  },
  "1": {
    "COL1": "whatever",
    "COL2": "val2",
    "COL3": "whatever",
  },
  "3": {
    "COL1": "whatever",
    "COL2": "val3",
    "COL3": "whatever",
  }    
} 

#variable containing users from the database
users_from_database = [
  ["val1"],
  ["val2"],
  ["val5"],
  ["val7"]
]

#This function is used to find element from the nested dictionaries(d)
def _check(element, d, pattern = 'COL2'):
  exist = False
  for k, user in d.iteritems():
    for key, item in user.iteritems():
      if key == pattern and item == element:
        exist = True
  return exist

#Finding which users should be removed from the database  
to_remove = []
for user in users_from_db:
  if not _check(user[0], users_from_agent):
    if user[0] not in to_remove:
      to_remove.append(user[0])

#to_remove list contains: [val5, val7"] 

Pythonアプローチを使用して同じ結果を得るより良い方法は何ですか? おそらく、私が Python の初心者であることを付け加える必要はありません (上記のコードを見ればわかると思います)。

4

3 に答える 3

1

Just use an error-safe dictionary lookup:

def _check(element, d, pattern = 'COL2'):
    for user in d.itervalues():
        if user.get(pattern) == element:
            return True
    return False

Or as a one liner:

def _check(element, d, pattern = 'COL2'):
    return any(user.get(pattern) == element for user in d.itervalues())

Or trying to do the entire job as a one-liner:

#Finding which users should be removed from the database  
to_remove = set(
    name
    for name in users_from_database.itervalues()
    if not any(user.get('COL2') == name for (user,) in users_from_client)
)

assert to_remove == {"val5", "val7"}

sets can make it ever more concise (and efficient):

to_remove = set(
    user for (user,) in users_from_database
) - set(
    user.get('COL2') for user in users_from_client
)

Your data structures are a bit wierd. Consider using:

users_from_client = [
  {
    "COL1": "whatever",
    "COL2": "val1",
    "COL3": "whatever",
  }, {
    "COL1": "whatever",
    "COL2": "val2",
    "COL3": "whatever",
  }, {
    "COL1": "whatever",
    "COL2": "val3",
    "COL3": "whatever",   
  }
] 

#variable containing users from the database
users_from_database = set(
  "val1",
  "val2",
  "val5",
  "val7"
)

Which reduces your code to:

to_remove = users_from_database - set(
    user.get('COL2') for user in users_from_client
)
于 2013-04-26T19:42:33.340 に答える
0

これを行うための非常にエレガントな方法はわかりませんが、コードにいくつかの小さな改善を加えることができます。

まず、 を使用していないkため、値だけを反復処理することもできます。次に、 を追跡する必要はありませんexists。一致するものが見つかったらすぐに戻ることができます。最後に、キーと値のペアをチェックしている場合は、タプルがアイテムに含まれているかどうかをテストできます。

def _check(element, d, pattern = 'COL2'):
  for user in d.itervalues():
    if (pattern, element) in user.items():
      return True
  return False
于 2013-04-26T19:36:34.413 に答える