帮助在元组匹配 Python 函数中使用 *args

发布于 2024-11-29 11:45:48 字数 1352 浏览 1 评论 0原文

我正在尝试在 python 中构建一个函数,如果 dict1 中的特定值与 dict2 中的特定值匹配,则该函数会生成两个字典的值。我的函数如下所示:

def dict_matcher(dict1, dict2, item1_pos, item2_pos):
"""Uses a tuple value from dict1 to search for a matching tuple value in dict2. If a match is found, the other values from dict1 and dict2 are returned."""
for item1 in dict1:
    for item2 in dict2:
        if dict1[item1][item1_pos] == dict2[item2][item2_pos]:
            yield(dict1[item1][2], dict2[item2][6])

我使用 dict_matcher 如下:

matches = [myresults for myresults in dict_matcher(dict1, dict2 , 2, 6)]
print(matches)

当我打印 matches 时,我得到正确匹配的 dict1 和 dict2 值的列表,如下所示:

[( '青蛙', '青蛙'), ('蜘蛛', '蜘蛛'), ('蟋蟀', '蟋蟀'), ('汉普斯特', '汉普斯特')]

我怎样才能向此函数添加变量参数,以便除了打印每个字典中的匹配值之外,我还可以在 dict1[item1][2] 和 dict2[item2][ 的实例中打印每个字典项目的其他值6] 匹配吗?我可以使用 *args 吗?感谢您的帮助。

编辑: 好吧,对于我想要做什么似乎有些困惑,所以让我尝试另一个例子。

dict1 = {1: ('青蛙', '绿色'), 2: ('蜘蛛', '蓝色'), 3: ('蟋蟀', '红色')}

dict2 = {a: ('青蛙', 12.34), b: ('猿', 22.33), c: ('狐猴', 90.21)}

dict_matcher(dict1, dict2, 0, 0) 会从 dict1 中找到 value[0] ,从 dict2 中找到 value[0] 的匹配值。在这种情况下,唯一的匹配是“frog”。我上面的函数就是这样做的。我想做的是扩展该函数,以便能够从字典项中打印出其他值,其中 dict1[value][0] == dict2[value][0] 我希望这样做在函数参数中指定。

I am trying to build a function in python that yields values of two dictionaries IF a particular value from dict1 matches a particular value of dict2. My function looks like this:

def dict_matcher(dict1, dict2, item1_pos, item2_pos):
"""Uses a tuple value from dict1 to search for a matching tuple value in dict2. If a match is found, the other values from dict1 and dict2 are returned."""
for item1 in dict1:
    for item2 in dict2:
        if dict1[item1][item1_pos] == dict2[item2][item2_pos]:
            yield(dict1[item1][2], dict2[item2][6])

I am using dict_matcher like this:

matches = [myresults for myresults in dict_matcher(dict1, dict2 , 2, 6)]
print(matches)

When I print matches I get a list of correctly matching dict1 and dict2 values like this:

[('frog', 'frog'), ('spider', 'spider'), ('cricket', 'cricket'), ('hampster', 'hampster')]

How can I add variable arguments to this function so that, in addition to printing the matching values from each dictionary, I can also print the other values of each dictionary item in instances where dict1[item1][2] and dict2[item2][6] match? Can I use *args? Thanks for the help.

EDIT:
Ok, there seems to be some confusion as to what I am trying to do so let me try another example.

dict1 = {1: ('frog', 'green'), 2: ('spider', 'blue'), 3: ('cricket', 'red')}

dict2 = {a: ('frog', 12.34), b: ('ape', 22.33), c: ('lemur', 90.21)}

dict_matcher(dict1, dict2, 0, 0) would find matching values for value[0] from dict1 and value[0] from dict2. In this case, the only match is 'frog'. My function above does this. What I am trying to do is extend the function to be able to print out other values from the dictionary items where dict1[value][0] == dict2[value][0] I want this to be specified in the function argument.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终陌 2024-12-06 11:45:48

您可以使用 切片对象

def dict_matcher(dict1, dict2, pos1, pos2, slicer1=(), slicer2=()):
    slice1 = slice(*slicer1) if slicer1 else slice(len(dict1))
    slice2 = slice(*slicer2) if slicer2 else slice(len(dict2))
    for data1 in dict1.values():
        for data2 in dict2.values():
            if data1[pos1] == data2[pos2]:
                yield data1[slice1], data2[slice2]

for result1, result2 in dict_matcher(my_dict, your_dict, 2, 6, (3, 8, 2), (2, 6)):
    print result1, result2
  • some_list[slice( 3, 8, 2)] 相当于 some_list[3:8:2]
    为您提供从以下开始的 some_list 的每个第二个元素
    第四个元素(索引为 3)到第八个元素。
  • some_list[slice(2, 6)] 相当于 some_list[2:6],给出
    从第三个元素开始的 some_list 的每个元素
    (索引为 2)直到第六个元素。
  • some_list[slice(7)] 相当于 some_list[:7],给你
    some_list 的每个元素,直到第七个元素。

如果您省略 slicer1/2 参数,该函数会假设您需要整个列表,并相应地设置切片。

另外,我删除了不必要的字典查找。

You could use slice objects:

def dict_matcher(dict1, dict2, pos1, pos2, slicer1=(), slicer2=()):
    slice1 = slice(*slicer1) if slicer1 else slice(len(dict1))
    slice2 = slice(*slicer2) if slicer2 else slice(len(dict2))
    for data1 in dict1.values():
        for data2 in dict2.values():
            if data1[pos1] == data2[pos2]:
                yield data1[slice1], data2[slice2]

for result1, result2 in dict_matcher(my_dict, your_dict, 2, 6, (3, 8, 2), (2, 6)):
    print result1, result2
  • some_list[slice(3, 8, 2)] is equivalent to some_list[3:8:2],
    giving you every second element of some_liststarting with the
    fourth element (which has index 3) up to the eighth element.
  • some_list[slice(2, 6)] is equivalent to some_list[2:6], giving
    you every element of some_liststarting with the third element
    (which has index 2) up to the sixth element.
  • some_list[slice(7)] is equivalent to some_list[:7], giving you
    every element of some_listup to the seventh element.

If you omit the slicer1/2 arguments, the function assumes you want the whole list and the slices are set accordingly.

Also, I removed unnecessary dictionary lookups.

离旧人 2024-12-06 11:45:48

你说你

matches = [myresults for myresults in dict_matcher(dict1, dict2 , 2, 6)]

应该这样称呼

matches = list(dict_matcher(dict1, dict2 , 2, 6))

它,它的签名是

def dict_matcher(dict1, dict2, item1_pos, item2_pos, *args):

所以传递了 4 个参数,以及 4 个命名参数。因此,*args 结果为args = None

我不确定你到底想要什么,但如果你这样做,

yield dict1[item1][item1_pos], dict2[item2][item2_pos]

你会得到与你从做得到的东西相同的东西

yield dict1[item1][2], dict2[item2][6]

如果你想得到整个匹配的项目,做

yield dict1[item1], dict2[item2]

如果你想从每个项目中得到一个项目,但不是匹配项目,请执行

def dict_matcher(dict1, dict2, item1_pos, item2_pos, other1_pos, other2_pos):

and

yield dict1[item1][other1_pos], dict2[item2][other2_pos]

matches = list(dict_matcher(dict1, dict2 , 2, 6, 3, 8)) 

其他操作,而不是 3 和 8。

如果您想要获得多个项目,但不是全部项目,请执行

def dict_matcher(dict1, dict2, item1_pos, item2_pos, other1_poss, other2_poss):

and

yield [dict1[item1][i] for i in other1_poss], [dict2[item2][i] for i in other2_poss]

matches = list(dict_matcher(dict1, dict2 , 2, 6, (2, 3), (6, 8))) 

其他操作,而不是 [2, 3] 和 [3, 8]。

如果这不是您的意思,请告诉我。

You said you're calling it as

matches = [myresults for myresults in dict_matcher(dict1, dict2 , 2, 6)]

You should be calling it as

matches = list(dict_matcher(dict1, dict2 , 2, 6))

and it's signature is

def dict_matcher(dict1, dict2, item1_pos, item2_pos, *args):

So 4 arguments passed, and 4 named arguments. So *args results in args = None.

I'm not sure exactly what you want, but if you do

yield dict1[item1][item1_pos], dict2[item2][item2_pos]

You'll get the same thing as you get from doing

yield dict1[item1][2], dict2[item2][6]

If you want to get the whole matching items, do

yield dict1[item1], dict2[item2]

If you want to get one item from each, but not the matching item, do

def dict_matcher(dict1, dict2, item1_pos, item2_pos, other1_pos, other2_pos):

and

yield dict1[item1][other1_pos], dict2[item2][other2_pos]

and

matches = list(dict_matcher(dict1, dict2 , 2, 6, 3, 8)) 

or whatever instead of 3 and 8.

If you want to get several, but not all items, do

def dict_matcher(dict1, dict2, item1_pos, item2_pos, other1_poss, other2_poss):

and

yield [dict1[item1][i] for i in other1_poss], [dict2[item2][i] for i in other2_poss]

and

matches = list(dict_matcher(dict1, dict2 , 2, 6, (2, 3), (6, 8))) 

or whatever instead of [2, 3] and [3, 8].

If this isn't what you meant, let me know.

等待我真够勒 2024-12-06 11:45:48

您想要指定任意数量的索引对来尝试比较匹配项吗?

像这样的东西吗?

def matcher(d1, d2, *args):
    indexes = zip(args[0::2], args[1::2])
    for a, b in indexes:
        for value1 in dict1.values():
            for value2 in dict2.values():
                x, y = value1[a], value2[b]
                    if x == y:
                        yield x, y

dict1 = {1: ('frog', 'green'), 2: ('spider', 'blue'), 3: ('cricket', 'red')}
dict2 = {a: ('frog', 12.34), b: ('ape', 22.33), c: ('lemur', 90.21)}

matches = list(matcher(d1, d2, 
                        0, 0, # first pair to search for matches
                        1, 1  # second pair, 
                        # ... and so on,
))

print matches
# [('frog', 'frog')]

我认为这不是很有用,但这样做就可以了。如果由于切片的魔力而指定奇数个参数,这仍然可以工作。然而,正因为如此,匹配器函数的接口很容易被错误地使用。

我强烈考虑类似的东西:

def matcher(d1, d2, indexes_to_check):
    ...
print list(matcher(d1, d2, [(0, 0), (1, 1), ...]))

def matcher(d1, d2, *indexes_to_check):
    ...
print list(matcher(d1, d2, (0, 0), (1, 1)))

You're looking to specify an arbitrary number of pairs of indexes to try to compare for matches?

Something like this?

def matcher(d1, d2, *args):
    indexes = zip(args[0::2], args[1::2])
    for a, b in indexes:
        for value1 in dict1.values():
            for value2 in dict2.values():
                x, y = value1[a], value2[b]
                    if x == y:
                        yield x, y

dict1 = {1: ('frog', 'green'), 2: ('spider', 'blue'), 3: ('cricket', 'red')}
dict2 = {a: ('frog', 12.34), b: ('ape', 22.33), c: ('lemur', 90.21)}

matches = list(matcher(d1, d2, 
                        0, 0, # first pair to search for matches
                        1, 1  # second pair, 
                        # ... and so on,
))

print matches
# [('frog', 'frog')]

I don't think this is terribly usable but this would do it. This will still sort of work if you specify odd numbers of args due to the magic of slicing. However, because of this the interface to your matcher function is going to be easy to use incorrectly.

I'd strongly consider something more like:

def matcher(d1, d2, indexes_to_check):
    ...
print list(matcher(d1, d2, [(0, 0), (1, 1), ...]))

def matcher(d1, d2, *indexes_to_check):
    ...
print list(matcher(d1, d2, (0, 0), (1, 1)))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文