将 *arg 放入可排序的元组中的正确方法是什么?

发布于 2024-12-04 16:44:32 字数 883 浏览 0 评论 0原文

我想要一个字典或元组,我可以根据用作 *arg 参数的对象的属性进行排序。我一直尝试这样做的方式只是给了我 AttributeErrors,这让我相信我做得很奇怪。

def function(*arg):
    items = {}
    for thing in arg:
        items.update({thing.name:thing})


    while True:
        for thing in items:
        ## lots of other code here, basically just a game loop.
        ## Problem is that the 'turn order' is based on whatever
        ## Python decides the order of arguments is inside "items".
        ## I'd like to be able to sort the dict based on each object's
        ## attributes (ie, highest 'thing.speed' goes first in the while loop)

问题是,当我尝试根据放入 function() 的对象的属性对“项目”进行排序时,它给出“AttributeError:'str'对象没有属性'attribute'”。这让我相信我要么以糟糕的方式解压 *arg,要么我试图以错误的方式做某事。

while True:
    for thing in sorted(items, key=attrgetter('attribute')):

...也不起作用,一直告诉我我正在尝试操纵“str”对象。我不在这里做什么?

I want a dict or tuple I can sort based on attributes of the objects I'm using as arguments for *arg. The way I've been trying to do it just gives me AttributeErrors, which leads me to believe I'm doing it weird.

def function(*arg):
    items = {}
    for thing in arg:
        items.update({thing.name:thing})


    while True:
        for thing in items:
        ## lots of other code here, basically just a game loop.
        ## Problem is that the 'turn order' is based on whatever
        ## Python decides the order of arguments is inside "items".
        ## I'd like to be able to sort the dict based on each object's
        ## attributes (ie, highest 'thing.speed' goes first in the while loop)

The problem is when I try to sort "items" based on an attribute of the objects I put into function(), it gives me "AttributeError: 'str' object has no attribute 'attribute'". Which leads me to believe I'm either unpacking *arg in a lousy way, or I'm trying to do something the wrong way.

while True:
    for thing in sorted(items, key=attrgetter('attribute')):

...doesn't work either, keeps telling me I'm trying to manipulate a 'str' object. What am I not doing here?

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

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

发布评论

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

评论(3

(り薆情海 2024-12-11 16:44:32

arg 已经一个元组,您可以按每个项目的属性进行排序:

def function(*args):
    for thing in sorted(args, key=attrgetter('attribute')):

当您迭代dict时,正如 sorted 所做的那样,您只获得键,而不是值。因此,如果您想使用 dict,您需要执行以下操作:

def function(*args):
    # or use a dict comprehension on 2.7+ 
    items = dict((thing.name, thing) for thing in args)

    # or just items.values on 3+
    for thing in sorted(items.itervalues(), key=attrgetter('attribute')):

按属性对参数进行实际排序。如果您希望 dict 的键也可用(此处不必要,因为键也是项目的属性),请使用类似以下内容的内容:

for name, thing in sorted(items.iteritems(), key=lambda item: item[1].attribute):

arg already is a tuple you can sort by an attribute of each item:

def function(*args):
    for thing in sorted(args, key=attrgetter('attribute')):

When you iterate over a dict, as sorted is doing, you just get the keys, not the values. So, if you want to use a dict, you need to do:

def function(*args):
    # or use a dict comprehension on 2.7+ 
    items = dict((thing.name, thing) for thing in args)

    # or just items.values on 3+
    for thing in sorted(items.itervalues(), key=attrgetter('attribute')):

to actually sort the args by an attribute. If you want the keys of the dict available as well (not necessary here because the key is also an attribute of the item), use something like:

for name, thing in sorted(items.iteritems(), key=lambda item: item[1].attribute):
站稳脚跟 2024-12-11 16:44:32

您的 items 是一个字典,您无法正确对字典进行排序。当您尝试将它用作可迭代对象时,它会默默地返回其键列表,这是一个字符串列表。创建字典后,您不会使用 arg

如果您不需要 dict 查找,因为您只是迭代它,则可以将 dict 替换为 2 元组列表(thing.name,thing),按任何属性对其进行排序并迭代它。如果您确实想要字典查找和排序,您还可以使用 Python 2.7 中的 collections.OrderedDict (对于早期版本,它作为单独的 ordereddict 包存在)。

Your items is a dict, you can't properly sort a dict. When you try to use it as an iterable, it silently returns its keys list, which is a list of strings. And you don't use your arg after creating a dict.

If you don't need dict lookup, as you just iterate through it, you can replace dict with list of 2-tuples (thing.name, thing), sort it by any attribute and iterate through it. You can also use collections.OrderedDict from Python 2.7 (it exists as a separate ordereddict package for earlier versions) if you really want both dict lookup and ordering.

开始看清了 2024-12-11 16:44:32

{编辑} 感谢 agf,我理解了这个问题。所以,我在下面写的内容本身就是一个很好的答案,但与上面的问题相关时就不是了……我把它放在这里是为了跟踪。


看了答案,我可能没有理解这个问题。但我的理解是:由于 args 是您提供给函数的参数元组,因此这些参数可能都不是具有 name 属性的对象。但是,查看您报告的错误,您将给出字符串参数。

也许一些插图会帮助我的描述:

>>> # defining a function using name attribute
>>> def f(*args):
...      for arg in args:
...           print arg.name
>>> # defining an object with a name attribute
>>> class o(object):
...     def __init__(self, name):
...          self.name = name
>>> # now applying the function on the previous object, and on a string
>>> f( o('arg 1'), 'arg 2' )
arg 1

Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    f(o('arg 1'), 'ets')
  File "<pyshell#3>", line 3, in f
    print arg.name
AttributeError: 'str' object has no attribute 'name'

这是失败的,因为字符串没有这样的属性。

对我来说,在您的代码中存在一个错误:您试图在输入上使用属性name,而没有验证它们是否具有这样的属性。也许您应该首先使用 hasattr 进行测试:

>>> if hasattr(arg, 'name'):
...     print arg.name
... else:
...     print arg

或者对输入进行一些检查,以验证它是否是已知具有所请求属性的给定类的实例。

{edit} Thanks to agf, I understood the problem. So, what I wrote below is a good answer in itself, but not when related to the question above... I let it here for the trace.


Looking to the answers, I may have not understood the question. But here's my understanding: as args is a tuple of arguments you give to your function, it's likely that none of these arguments is an object with a name attribute. But, looking to the errors you report, you're giving string arguments.

Maybe some illustration will help my description:

>>> # defining a function using name attribute
>>> def f(*args):
...      for arg in args:
...           print arg.name
>>> # defining an object with a name attribute
>>> class o(object):
...     def __init__(self, name):
...          self.name = name
>>> # now applying the function on the previous object, and on a string
>>> f( o('arg 1'), 'arg 2' )
arg 1

Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    f(o('arg 1'), 'ets')
  File "<pyshell#3>", line 3, in f
    print arg.name
AttributeError: 'str' object has no attribute 'name'

This is failing as strings have no such attribute.

For me, in your code, there is a mistake: you're trying to use attribute name on your inputs, without ever verifying that they have such an attribute. Maybe you should test with hasattr first:

>>> if hasattr(arg, 'name'):
...     print arg.name
... else:
...     print arg

or with some inspection on the input, to verify if it's an instance of a given class, known to have the requested attribute.

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