20

我是 Python 的初学者,但我一直在尝试这种语法,但我无法弄清楚——这真是令人困惑。

crucial = {'eggs': '','ham': '','cheese': ''}
dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}

if crucial.keys() in dishes.keys():
    print dishes[value]

我想要做的是——如果关键在eggs盘子里有一个键(在这种情况下,),它会返回2。看起来很简单,但我相信我一定在某处弄乱了某种语法。如果有人可以指导我一点,那将不胜感激。

我比较的真正字典大约有 150 个键长,但我希望这段代码足够简单。

4

7 回答 7

23

您需要遍历 key 中的键并将每个键与菜键进行比较。因此,您的代码的直接修改版本。

for key in crucial.keys():
    if key in dishes.keys():
        print dishes[key]

可以更好地表述为(无需指定 .keys):

for key in crucial:
    if key in dishes:
        print dishes[key]
于 2012-12-05T01:36:54.180 回答
6

如果您使用的是 Python 3,则keys字典的方法遵循set接口。这意味着您可以使用&运算符对两个字典的键进行交集。

for key in crucial.keys() & dishes.keys():
    print(dishes[key])

或者,如果您需要值列表:

result = [dishes[key] for key in crucial.keys() & dishes.keys()]

在 Python 2 中,您可以通过显式创建集合(可能来自iterkeys生成器)来管理相同的事情,但可能最好简单地对键进行循环,就像其他几个答案所建议的那样。

这是循环的一个变体,我认为我没有见过其他人这样做。外层循环从 dict 中获取键和值dishes,因此您不需要单独按键查找值。

for key, value in dishes.iteritems(): # use items() in Python 3
    if key in crucial:
        print value
于 2012-12-05T02:26:41.320 回答
2

使用列表理解很好

[ dishes[x] for x in crucial if dishes.has_key(x) ]

或者,根据 gnibbler:

[ dishes[x] for x in crucial if x in dishes ]

该表达式将迭代critical中的每个键,如果键在dish中,它将返回dish中相同键的值,最后返回所有匹配值的列表。

或者,您可以使用这种方式, (set (crucial) & set(dishes)) 返回两个集合的公共键,然后迭代这个集合并返回菜式中的值。

[ dishes[x] for x in set (crucial) & set(dishes) ]
于 2012-12-05T01:44:41.683 回答
0

has_key()已在 Python 3 中删除:http: //docs.python.org/3.1/whatsnew/3.0.html#builtins

相反,您可以使用:

[dishes[key] for key in crucial.keys() if key in dishes]

这里使用的方法称为列表推导。你可以在这里读到它:

http://docs.python.org/2/tutorial/datastructures.html#list-comprehensions

于 2012-12-05T01:47:30.623 回答
0

如果您还不熟悉 Python 的 REPL(Read-Evaluate-Print-Loop - 您输入代码的地方,按 Enter 并立即计算),这将是一个很好的工具。

因此,让我们开始分解您的代码。

crucial = {'eggs': '','ham': '','cheese': ''}
dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}

很简单。crucials尽管我注意到您在字典中没有任何值。我不确定这是否是您示例的缩写,或者您是否只是关心键。如果您只关心键,那么我假设您使用字典是为了确保唯一性。在这种情况下,您应该检查set数据结构

例子:

crutial = set(['cheese', 'eggs', 'ham'])

继续我们有

if crucial.keys() in dishes.keys():

在这里,您使用的是in比较运算符。例子:

5 in [5, 4] #True
3 in [5, 4] #False

如果我们评估crucial.keys()dishes.keys()得到

 >>> crucial.keys()
 ['cheese', 'eggs', 'ham']
 >>> dishes.keys()
 ['eggs', 'bacon', 'sausage', 'spam']

所以在执行期间你的代码评估为

 ['cheese', 'eggs', 'ham'] in ['eggs', 'bacon', 'sausage', 'spam']

它返回False是因为值['eggs', 'bacon', 'sausage'](这是一个列表)不在列表中['eggs', 'bacon', 'sausage', 'spam'](实际上该列表中没有列表,只有字符串)。

因此,您正在评估为

if False:
    print dishes[value] #note value is not defined.

看起来您已经混合/混淆了in返回布尔值的运算符和 for 迭代器 ( for item in collection)。这种事情有一种语法。它被称为列表推导,您可以在@ShawnZhang 和@kmad 的答案中找到示例。您可以将其视为过滤和修改(映射)集合的简洁方法,并返回一个列表作为结果。我不想在这里太深入,否则我最终会介绍函数式编程。

您的另一个选择是分别使用for .. in迭代和in运算符。这是@timc 给出的解决方案。对于初学者来说,这样的解决方案可能更熟悉或更容易。它清楚地区分了迭代和过滤的行为。它也更像是用其他没有与列表推导等效的编程语言编写的内容。那些经常使用 Python 工作的人可能会喜欢理解语法。

于 2012-12-05T02:11:15.420 回答
0

您可以使用Counter

import operator
from collections import Counter

def mio(si, ti):
    si = Counter(s)
    ti = Counter(t)
    if operator.eq(si, ti):
        return True
    return False
于 2021-05-14T04:15:41.730 回答
-1
crucial = {'eggs': '','ham': '','cheese': ''}
dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
for key in set(dishes.keys()) & set(crucial.keys()):
    print dishes[key]

同样,您可以拥有set(dishes.keys()) - set(crucial.keys())set(dishes.keys()) | set(crucial.keys())set(dishes.keys()) ^ set(crucial.keys())

于 2016-12-25T04:16:25.927 回答