方法调用可以链接到“set()”吗? 内置? (那么为何不?)

发布于 2024-07-17 06:51:48 字数 492 浏览 3 评论 0原文

如果我尝试:

mi_list = ['three', 'small', 'words']
mi_set = set(mi_list)
mi_set.remove('small')
print mi_set  

我得到:

set(['three', 'words'])  

这就是我所期望的。 而如果我尝试:

mi_list = ['three', 'small', 'words']
mi_set = set(mi_list).remove('small')
print mi_set

我得到:

None

为什么?

我怀疑有一个线索,如果我尝试删除不存在的元素(例如“大”),则会报告错误:

KeyError: 'big'

If I try:

mi_list = ['three', 'small', 'words']
mi_set = set(mi_list)
mi_set.remove('small')
print mi_set  

I get:

set(['three', 'words'])  

which is what I expect. Whereas If I try:

mi_list = ['three', 'small', 'words']
mi_set = set(mi_list).remove('small')
print mi_set

I get:

None

Why?

I suspect there's a clue in that if I try to remove an element that isn't present - eg 'big' - an error gets reported:

KeyError: 'big'

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

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

发布评论

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

评论(6

遇到 2024-07-24 06:51:48

set.remove 不返回任何内容(None)。

您的代码将 set.remove 的返回值分配给变量 mi_set。 因此,mi_set 为 None。

set.remove returns nothing (None).

Your code assigns the return value of set.remove to the variable mi_set. Therefore, mi_set is None.

安稳善良 2024-07-24 06:51:48

Python 中有一个通用约定,导致副作用的方法会返回没有。。 示例包括 list.sort、list.append、set.add、set.remove、dict.update 等。

这本质上是为了帮助您避免错误。 假设您有一个名为 mi_set 的集合。 如果你可以写:

mi_set2 = mi_set.remove('small')

那么读者可能会认为:“mi_set2mi_set 不同”。 但事实并非如此! 这种混乱可能会导致由于错误地共享数据结构而导致的微妙错误。 因此,通过返回 None,Python 会强制您记住上面列出的方法会修改对象,而不是创建新对象。

另请参阅此处的长讨论。 尽管请注意,自该线程以来已添加了 sorted()reversed() 等方法。

[请注意,由于历史原因,list.pop 是此规则的一个例外 - 它允许您像堆栈一样使用列表。 即使这样,它也会返回被删除的对象,而不是列表。]

There is a general convention in python that methods which cause side-effects return None. Examples include list.sort, list.append, set.add, set.remove, dict.update, etc.

This is essentially to help you avoid bugs. Say you had a set called mi_set. If you could write:

mi_set2 = mi_set.remove('small')

then a reader might think: "mi_set2 is different from mi_set". But this would not be the case! And the confusion might lead to subtle bugs caused by mistakenly sharing data structures. So by returning None, python forces you to remember that methods like those I listed above modify objects, rather than creating new ones.

See also long discussion here. Although note that methods like sorted() and reversed() have been added since that thread.

[note that list.pop is an exception to this rule, for historical reasons – it lets you use a list like a stack. And even then, it returns the object removed, rather than the list.]

起风了 2024-07-24 06:51:48

为什么它返回None? 因为 .remove、.add 等返回 None :) 就是这样。 他们不支持链接。

set 使用方法来就地更改它。 您可以创建自己的使用链接的 set 版本,但这可能会导致一些问题:

class chain_set(set):
   def chain_add(self, x):
      newself = self.copy()
      newself.add(x)
      return newself

cs = chain_set([1,2,3,4])
cs.chain_add(5)
# chain_set([1, 2, 3, 4, 5])
cs.chain_add(7)
# chain_set([1, 2, 3, 4, 7])
cs.chain_add(7).chain_add(8)
# chain_set([1, 2, 3, 4, 7, 8])

问题是 - 您是否期望 cs 本身发生变化?

您是否总是想要修改原始集(可能会产生一些难以发现的错误),或者您是否想每次都复制该集(对于更大的集可能会很慢)。 如果你知道你需要什么行为并且你记得它 - 只需继续你自己的设置实现即可。

Why does it return None? Because .remove, .add, etc. return None :) That's it. They do not support chaining.

set is using methods that change it in place. You could create your own version of set that uses chaining, but that can cause some problems:

class chain_set(set):
   def chain_add(self, x):
      newself = self.copy()
      newself.add(x)
      return newself

cs = chain_set([1,2,3,4])
cs.chain_add(5)
# chain_set([1, 2, 3, 4, 5])
cs.chain_add(7)
# chain_set([1, 2, 3, 4, 7])
cs.chain_add(7).chain_add(8)
# chain_set([1, 2, 3, 4, 7, 8])

The problem is - do you expect cs itself to change?

Do you always want to modify the original set (might create some hard to find bugs) or do you want to copy the set every time (might be slow with bigger sets). If you know what behaviour you need and you remember about it - just go ahead with your own set implementation.

﹏半生如梦愿梦如真 2024-07-24 06:51:48

在您的情况下,要使用的方法是使用 difference 成员:

>>> a = set(["a", "b", "c"])
>>> a = a.difference(["a"])
>>> print a
set(['c', 'b'])

区别在于 remove 作用于当前集(修改一个集合的 python 库对象成员函数)实例通常返回 None),而 difference 创建并返回一个新集合。

The way to go, in your case, would be to use the difference member:

>>> a = set(["a", "b", "c"])
>>> a = a.difference(["a"])
>>> print a
set(['c', 'b'])

The difference is that remove acts on the current set (python library object member functions that modify an instance usually return None), whereas difference creates and returns a new set.

回忆凄美了谁 2024-07-24 06:51:48

您确定 remove 函数返回一个值吗?

Are you sure that the remove function returns a value?

始终不够 2024-07-24 06:51:48

remove 修改原始集而不返回任何内容(或者更确切地说,它返回 None)。 此示例显示当您对原始对象调用remove时会发生什么情况:

Python 3.0.1 (r301:69561, Feb 13 2009, 20:04:18) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> lst = [1,2,3]
>>> s1 = set(lst)
>>> s1
{1, 2, 3}
>>> s2 = s1.remove(2)  # instead of reassigning s1, I save the result of remove to s2
>>> s1
{1, 3}  # *** 2 is not an element in the original set ***
>>> s2  # s2 is not a set at all!
>>> 

为了回答问题的其他部分,异常表明remove尝试从集合中删除参数,但不能,因为参数不在集合中放。 相反,remove 返回 None 表示成功。

remove modifies the original set without returning anything (or rather, it returns None). This example shows what happens to the original object when you call remove on it:

Python 3.0.1 (r301:69561, Feb 13 2009, 20:04:18) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> lst = [1,2,3]
>>> s1 = set(lst)
>>> s1
{1, 2, 3}
>>> s2 = s1.remove(2)  # instead of reassigning s1, I save the result of remove to s2
>>> s1
{1, 3}  # *** 2 is not an element in the original set ***
>>> s2  # s2 is not a set at all!
>>> 

To answer the other part of your question, the exception indicates that remove tried to remove the argument from the set, but couldn't because the argument is not in the set. Conversely, remove returns None to indicate success.

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