标签归档:syntax

python字符串前的a前缀是什么意思?

问题:python字符串前的a前缀是什么意思?

在python源代码中,我偶然发现在类似如下的字符串之前看到一个小b

b"abcdef"

我知道u表示unicode字符串的r前缀和原始字符串文字的前缀。

b它看起来像一个没有任何前缀的纯字符串,它代表什么?在哪种源代码中有用?

In a python source code I stumbled upon I’ve seen a small b before a string like in:

b"abcdef"

I know about the u prefix signifying a unicode string, and the r prefix for a raw string literal.

What does the b stand for and in which kind of source code is it useful as it seems to be exactly like a plain string without any prefix?


回答 0

这是Python3 bytes 文字。在Python 2.5和更早版本中不存在此前缀(等效于2.x的纯字符串,而3.x的纯字符串等效u于2.x中带前缀的文字)。在Python 2.6+中,它等效于纯字符串,以与3.x兼容

This is Python3 bytes literal. This prefix is absent in Python 2.5 and older (it is equivalent to a plain string of 2.x, while plain string of 3.x is equivalent to a literal with u prefix in 2.x). In Python 2.6+ it is equivalent to a plain string, for compatibility with 3.x.


回答 1

b前缀表示一个bytes字符串常量

如果您看到它在Python 3源代码中使用过,该表达式将创建一个bytes对象,而不是常规Unicode str对象。如果您看到它在Python Shell中回显,或者作为列表,字典或其他容器内容的一部分回显,那么您会看到bytes使用此符号表示的对象。

bytes对象基本上包含一个介于0-255之间的整数序列,但是当表示这些对象时,Python 会将这些字节显示为ASCII码点,以使其更易于读取其内容。外部任何字节可打印的ASCII字符范围被示为转义序列(例如\n\x82等)。相反,您可以同时使用ASCII字符和转义序列来定义字节值。对于ASCII值,使用其数字值(例如b'A'== b'\x41'

因为bytes对象由整数序列组成,所以您可以bytes从其他任何整数序列(其值在0-255范围内)构造一个对象,例如列表:

bytes([72, 101, 108, 108, 111])

和索引给你回的整数(但切片产生一个新bytes值;对于上面的例子中,value[0]给你72,但是value[:1]b'H'作为72是用于大写字母的ASCII码点ħ)。

bytes模拟二进制数据,包括编码文本。如果您的bytes值确实包含文本,则需要先使用正确的编解码器对其进行解码。例如,如果数据编码为UTF-8,则可以使用以下方法获取Unicode str值:

strvalue = bytesvalue.decode('utf-8')

相反,要从str对象中的文本转到bytes需要编码。您需要确定要使用的编码。默认是使用UTF-8,但是您所需要的很大程度上取决于您的用例:

bytesvalue = strvalue.encode('utf-8')

您也可以使用构造函数bytes(strvalue, encoding)执行相同的操作。

解码和编码方法都使用一个额外的参数来指定应如何处理错误

Python 2版本2.6和2.7还支持使用b'..'字符串文字语法创建字符串文字,以简化适用于Python 2和3的代码。

bytes对象是不变的,就像str字符串一样。如果您需要一个可变的字节值,请使用一个bytearray()对象

The b prefix signifies a bytes string literal.

If you see it used in Python 3 source code, the expression creates a bytes object, not a regular Unicode str object. If you see it echoed in your Python shell or as part of a list, dict or other container contents, then you see a bytes object represented using this notation.

bytes objects basically contain a sequence of integers in the range 0-255, but when represented, Python displays these bytes as ASCII codepoints to make it easier to read their contents. Any bytes outside the printable range of ASCII characters are shown as escape sequences (e.g. \n, \x82, etc.). Inversely, you can use both ASCII characters and escape sequences to define byte values; for ASCII values their numeric value is used (e.g. b'A' == b'\x41')

Because a bytes object consist of a sequence of integers, you can construct a bytes object from any other sequence of integers with values in the 0-255 range, like a list:

bytes([72, 101, 108, 108, 111])

and indexing gives you back the integers (but slicing produces a new bytes value; for the above example, value[0] gives you 72, but value[:1] is b'H' as 72 is the ASCII code point for the capital letter H).

bytes model binary data, including encoded text. If your bytes value does contain text, you need to first decode it, using the correct codec. If the data is encoded as UTF-8, for example, you can obtain a Unicode str value with:

strvalue = bytesvalue.decode('utf-8')

Conversely, to go from text in a str object to bytes you need to encode. You need to decide on an encoding to use; the default is to use UTF-8, but what you will need is highly dependent on your use case:

bytesvalue = strvalue.encode('utf-8')

You can also use the constructor, bytes(strvalue, encoding) to do the same.

Both the decoding and encoding methods take an extra argument to specify how errors should be handled.

Python 2, versions 2.6 and 2.7 also support creating string literals using b'..' string literal syntax, to ease code that works on both Python 2 and 3.

bytes objects are immutable, just like str strings are. Use a bytearray() object if you need to have a mutable bytes value.


使用Python,“ wb”在此代码中是什么意思?

问题:使用Python,“ wb”在此代码中是什么意思?

码:

file('pinax/media/a.jpg', 'wb')

Code:

file('pinax/media/a.jpg', 'wb')

回答 0

文件模式,写入和二进制。由于您正在编写.jpg文件,因此看起来不错。

但是,如果您应该阅读该jpg文件,则需要使用 'rb'

更多信息

在Windows上,附加到模式的’b’以二进制模式打开文件,因此也有’rb’,’wb’和’r + b’之类的模式。Windows上的Python区分文本文件和二进制文件。当读取或写入数据时,文本文件中的行尾字符会自动更改。这种对文件数据的幕后修改对于ASCII文本文件而言是很好的选择,但它会破坏JPEG或EXE文件中的二进制数据。

File mode, write and binary. Since you are writing a .jpg file, it looks fine.

But if you supposed to read that jpg file you need to use 'rb'

More info

On Windows, ‘b’ appended to the mode opens the file in binary mode, so there are also modes like ‘rb’, ‘wb’, and ‘r+b’. Python on Windows makes a distinction between text and binary files; the end-of-line characters in text files are automatically altered slightly when data is read or written. This behind-the-scenes modification to file data is fine for ASCII text files, but it’ll corrupt binary data like that in JPEG or EXE files.


回答 1

wb指示文件被打开以二进制方式写作。

当以二进制模式写入时,Python在写入文件时不会对数据进行任何更改。但是,在文本模式下(bw或在用或指定文本模式时排除时wt),Python将基于默认文本编码对文本进行编码。此外,Python会将行尾(\n)转换为特定于平台的行尾,这会破坏二进制文件(例如exepng文件)。

因此,在编写文本文件时(无论是使用纯文本还是基于文本的格式,如CSV)都应使用文本模式,而在编写非文本文件(如图像)时,则必须使用二进制模式。

参考文献:

https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files https://docs.python.org/3/library/functions.html#open

The wb indicates that the file is opened for writing in binary mode.

When writing in binary mode, Python makes no changes to data as it is written to the file. In text mode (when the b is excluded as in just w or when you specify text mode with wt), however, Python will encode the text based on the default text encoding. Additionally, Python will convert line endings (\n) to whatever the platform-specific line ending is, which would corrupt a binary file like an exe or png file.

Text mode should therefore be used when writing text files (whether using plain text or a text-based format like CSV), while binary mode must be used when writing non-text files like images.

References:

https://docs.python.org/3/tutorial/inputoutput.html#reading-and-writing-files https://docs.python.org/3/library/functions.html#open


回答 2

这就是打开文件的方式。“ wb”表示您正在写入文件(w),并且您正在以二进制模式(b)进行写入。

查看文档以了解更多信息:clicky

That is the mode with which you are opening the file. “wb” means that you are writing to the file (w), and that you are writing in binary mode (b).

Check out the documentation for more: clicky


使用哪个更合适:lambda函数或嵌套函数(’def’)?

问题:使用哪个更合适:lambda函数或嵌套函数(’def’)?

我主要使用lambda函数,但有时使用似乎提供相同行为的嵌套函数。

这是一些琐碎的示例,如果在另一个函数中找到它们,它们在功能上会做同样的事情:

Lambda函数

>>> a = lambda x : 1 + x
>>> a(5)
6

嵌套功能

>>> def b(x): return 1 + x

>>> b(5)
6

使用一个相对于另一个有优势吗?(性能?可读性?局限性?一致性?等)

有关系吗 如果不这样做,那确实违反了Python原则:

应该有一种(最好只有一种)明显的方式来做到这一点

I mostly use lambda functions but sometimes use nested functions that seem to provide the same behavior.

Here are some trivial examples where they functionally do the same thing if either were found within another function:

Lambda function

>>> a = lambda x : 1 + x
>>> a(5)
6

Nested function

>>> def b(x): return 1 + x

>>> b(5)
6

Are there advantages to using one over the other? (Performance? Readability? Limitations? Consistency? etc.)

Does it even matter? If it doesn’t then does that violate the Pythonic principle:

There should be one—and preferably only one—obvious way to do it.


回答 0

如果需要将分配lambda给名称,请改用a defdefs只是分配的语法糖,因此结果是相同的,并且它们更具灵活性和可读性。

lambdas只能使用一次,丢弃没有名称的函数。

但是,这种用例很少见。您很少需要传递未命名的函数对象。

内建函数map()filter()需要函数对象,但是列表理解生成器表达式通常比那些函数更具可读性,并且可以覆盖所有用例,而无需使用lambda。

对于情况下,你真的需要一个小的函数对象,你应该使用operator模块的功能,如operator.add代替lambda x, y: x + y

如果您仍然需要一些lambda未涵盖的内容,则可以考虑编写def,以提高可读性。如果功能比operator模块中的功能更复杂,则a def可能更好。

因此,现实世界中的好用lambda例非常少见。

If you need to assign the lambda to a name, use a def instead. defs are just syntactic sugar for an assignment, so the result is the same, and they are a lot more flexible and readable.

lambdas can be used for use once, throw away functions which won’t have a name.

However, this use case is very rare. You rarely need to pass around unnamed function objects.

The builtins map() and filter() need function objects, but list comprehensions and generator expressions are generally more readable than those functions and can cover all use cases, without the need of lambdas.

For the cases you really need a small function object, you should use the operator module functions, like operator.add instead of lambda x, y: x + y

If you still need some lambda not covered, you might consider writing a def, just to be more readable. If the function is more complex than the ones at operator module, a def is probably better.

So, real world good lambda use cases are very rare.


回答 1

实际上,对我来说有两个区别:

首先是关于他们做什么以及他们返回什么:

  • def是不返回任何内容并在本地命名空间中创建“名称”的关键字。

  • lambda是一个关键字,它返回一个函数对象,并且不在本地命名空间中创建“名称”。

因此,如果您需要调用带有函数对象的函数,则在一行python代码中执行此操作的唯一方法是使用lambda。def没有等效功能。

在某些框架中,这实际上很常见。例如,我经常使用Twisted

d.addCallback(lambda result: setattr(self, _someVariable, result))

是很常见的,并且对lambda更为简洁。

第二点区别是允许实际执行的功能。

  • 用’def’定义的函数可以包含任何python代码
  • 用“ lambda”定义的函数必须求值为表达式,因此不能包含诸如print,import,raise,…之类的语句。

例如,

def p(x): print x

如预期般运作

lambda x: print x

是一个SyntaxError。

当然,也有变通方法-代替printsys.stdout.write,或import__import__。但是通常情况下,最好还是使用一个函数。

Practically speaking, to me there are two differences:

The first is about what they do and what they return:

  • def is a keyword that doesn’t return anything and creates a ‘name’ in the local namespace.

  • lambda is a keyword that returns a function object and does not create a ‘name’ in the local namespace.

Hence, if you need to call a function that takes a function object, the only way to do that in one line of python code is with a lambda. There’s no equivalent with def.

In some frameworks this is actually quite common; for example, I use Twisted a lot, and so doing something like

d.addCallback(lambda result: setattr(self, _someVariable, result))

is quite common, and more concise with lambdas.

The second difference is about what the actual function is allowed to do.

  • A function defined with ‘def’ can contain any python code
  • A function defined with ‘lambda’ has to evaluate to an expression, and can thus not contain statements like print, import, raise, …

For example,

def p(x): print x

works as expected, while

lambda x: print x

is a SyntaxError.

Of course, there are workarounds – substitute print with sys.stdout.write, or import with __import__. But usually you’re better off going with a function in that case.


回答 2

Guido van Rossum 在这次采访中说,他希望自己不要让“ lambda”进入Python:

问:您最不满意Python的什么功能?

有时我太快地接受了贡献,后来才意识到这是一个错误。一个例子就是一些函数式编程功能,例如lambda函数。lambda是一个关键字,可让您创建一个小的匿名函数;内置函数(例如map,filter和reduce)可在序列类型(例如列表)上运行该函数。

在实践中,结果并非如此。Python只有两个范围:本地和全局。这使编写lambda函数很痛苦,因为您经常想在lambda定义的作用域中访问变量,但由于这两个作用域而不能。有办法解决这个问题,但这有点不合时宜。在Python中,通常只使用for循环而不是搞乱lambda函数似乎容易得多。只有当已有内置功能可以满足您的需求时,地图和朋友才能正常工作。

恕我直言,Iambdas有时可能很方便,但是通常以可读性为代价很方便。你能告诉我这是怎么做的:

str(reduce(lambda x,y:x+y,map(lambda x:x**x,range(1,1001))))[-10:]

我写了它,花了我一分钟才弄清楚。这是来自欧拉计划-我不会说哪个问题,因为我讨厌剧透,但是它只需要0.124秒即可:)

In this interview, Guido van Rossum says he wishes he hadn’t let ‘lambda’ into Python:

Q. What feature of Python are you least pleased with?

Sometimes I’ve been too quick in accepting contributions, and later realized that it was a mistake. One example would be some of the functional programming features, such as lambda functions. lambda is a keyword that lets you create a small anonymous function; built-in functions such as map, filter, and reduce run a function over a sequence type, such as a list.

In practice, it didn’t turn out that well. Python only has two scopes: local and global. This makes writing lambda functions painful, because you often want to access variables in the scope where the lambda was defined, but you can’t because of the two scopes. There’s a way around this, but it’s something of a kludge. Often it seems much easier in Python to just use a for loop instead of messing around with lambda functions. map and friends work well only when there’s already a built-in function that does what you want.

IMHO, Iambdas can be convenient sometimes, but usually are convenient at the expense of readibility. Can you tell me what this does:

str(reduce(lambda x,y:x+y,map(lambda x:x**x,range(1,1001))))[-10:]

I wrote it, and it took me a minute to figure it out. This is from Project Euler – i won’t say which problem because i hate spoilers, but it runs in 0.124 seconds :)


回答 3

对于n = 1000,这是调用函数与lambda的时间:

In [11]: def f(a, b):
             return a * b

In [12]: g = lambda x, y: x * y

In [13]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    f(a, b)
   ....:
100 loops, best of 3: 285 ms per loop

In [14]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    g(a, b)
   ....:
100 loops, best of 3: 298 ms per loop

In [15]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    (lambda x, y: x * y)(a, b)
   ....:
100 loops, best of 3: 462 ms per loop

For n=1000 here’s some timeit’s of calling a function vs a lambda:

In [11]: def f(a, b):
             return a * b

In [12]: g = lambda x, y: x * y

In [13]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    f(a, b)
   ....:
100 loops, best of 3: 285 ms per loop

In [14]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    g(a, b)
   ....:
100 loops, best of 3: 298 ms per loop

In [15]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    (lambda x, y: x * y)(a, b)
   ....:
100 loops, best of 3: 462 ms per loop

回答 4

性能:

创建一个功能lambda速度稍快比创建它def。差异是由于def在locals表中创建了一个名称条目。生成的函数具有相同的执行速度。


可读性:

对于大多数Python用户而言,Lambda函数的可读性较差,但在某些情况下也更为简洁。考虑从使用非函数例程转换为函数例程:

# Using non-functional version.

heading(math.sqrt(v.x * v.x + v.y * v.y), math.atan(v.y / v.x))

# Using lambda with functional version.

fheading(v, lambda v: math.sqrt(v.x * v.x + v.y * v.y), lambda v: math.atan(v.y / v.x))

# Using def with functional version.

def size(v):
    return math.sqrt(v.x * v.x + v.y * v.y)

def direction(v):
    return math.atan(v.y / v.x)

deal_with_headings(v, size, direction)

如您所见,在lambda您只需要添加lambda v:到原始非功能性版本以转换为功能性版本的意义上,该版本更短且更“容易” 。它也更加简洁。但是请记住,许多Python用户会对lambda语法感到困惑,因此,您失去的长度和真正的复杂性可能会在其他编码人员的困惑中重新获得。


局限性:

  • lambda 除非分配给变量名称,否则函数只能使用一次。
  • lambda分配给变量名的def函数比函数没有优势。
  • lambda 功能可能很难或无法腌制。
  • def 必须仔细选择函数的名称,以使其具有合理的描述性和唯一性,或者至少在范围内未使用。

一致性:

Python大多避免使用函数式编程约定,而倾向于使用过程性和更简单的目标语义。该lambda操作员站直接的对比这种偏见。此外,作为已经流行的替代方法def,该lambda函数为您的语法增加了多样性。有些人会认为这不太一致。


预先存在的功能:

正如其他人所指出的lambda,该领域的许多用途可以由operator或其他模块的成员代替。例如:

do_something(x, y, lambda x, y: x + y)
do_something(x, y, operator.add)

在许多情况下,使用预先存在的功能可以使代码更具可读性。


Python原则:“应该有一种-最好只有一种-显而易见的方法”

这类似于真理教义的单一来源。不幸的是,单行之道的原则一直是Python的渴望,而不是真正的指导原则。考虑一下Python中非常强大的数组理解。它们在功能上等效于mapfilter函数:

[e for e in some_array if some_condition(e)]
filter(some_array, some_condition)

lambdadef一样。

这是一个见解,但是我想说,Python语言中用于一般用途的任何东西如果没有明显破坏任何东西,都足够“ Pythonic”。

Performance:

Creating a function with lambda is slightly faster than creating it with def. The difference is due to def creating a name entry in the locals table. The resulting function has the same execution speed.


Readability:

Lambda functions are somewhat less readable for most Python users, but also much more concise in some circumstances. Consider converting from using non-functional to functional routine:

# Using non-functional version.

heading(math.sqrt(v.x * v.x + v.y * v.y), math.atan(v.y / v.x))

# Using lambda with functional version.

fheading(v, lambda v: math.sqrt(v.x * v.x + v.y * v.y), lambda v: math.atan(v.y / v.x))

# Using def with functional version.

def size(v):
    return math.sqrt(v.x * v.x + v.y * v.y)

def direction(v):
    return math.atan(v.y / v.x)

deal_with_headings(v, size, direction)

As you can see, the lambda version is shorter and “easier” in the sense that you only need to add lambda v: to the original non-functional version to convert to the functional version. It’s also a lot more concise. But remember, a lot of Python users will be confused by the lambda syntax, so what you lose in length and real complexity might be gained back in confusion from fellow coders.


Limitations:

  • lambda functions can only be used once, unless assigned to a variable name.
  • lambda functions assigned to variable names have no advantage over def functions.
  • lambda functions can be difficult or impossible to pickle.
  • def functions’ names must be carefully chosen to be reasonably descriptive and unique or at least otherwise unused in scope.

Consistency:

Python mostly avoids functional programming conventions in favor of procedural and simpler objective semantics. The lambda operator stands in direct contrast to this bias. Moreover, as an alternative to the already prevalent def, the lambda function adds diversity to your syntax. Some would consider that less consistent.


Pre-existing functions:

As noted by others, many uses of lambda in the field can be replaced by members of the operator or other modules. For instance:

do_something(x, y, lambda x, y: x + y)
do_something(x, y, operator.add)

Using the pre-existing function can make code more readable in many cases.


The Pythonic principle: “There should be one—and preferably only one—obvious way to do it”

That’s similar to the single source of truth doctrine. Unfortunately, the single-obvious-way-to-do-it principle has always been more an wistful aspiration for Python, rather than a true guiding principal. Consider the very-powerful array comprehensions in Python. They are functionally equivalent to the map and filter functions:

[e for e in some_array if some_condition(e)]
filter(some_array, some_condition)

lambda and def are the same.

It’s a matter of opinion, but I would say that anything in the Python language intended for general use which doesn’t obviously break anything is “Pythonic” enough.


回答 5

更可取的是:lambda函数还是嵌套函数(def)?

与常规函数相比,使用lambda有一个优点:它们是在表达式中创建的。

有几个缺点:

  • 没有名字(只是'<lambda>'
  • 没有文档字符串
  • 没有注释
  • 没有复杂的陈述

它们也是相同类型的对象。由于这些原因,我通常更喜欢使用def关键字而不是lambdas 创建函数。

要点-它们是同一类型的对象

Lambda产生与常规函数相同类型的对象

>>> l = lambda: 0
>>> type(l)
<class 'function'>
>>> def foo(): return 0
... 
>>> type(foo)
<class 'function'>
>>> type(foo) is type(l)
True

由于lambda是函数,因此它们是一流的对象。

Lambda和功能:

  • 可以作为参数传递(与常规函数相同)
  • 在外部函数中创建时,将成为该外部函数的局部变量的闭包

但是,默认情况下,lambda缺少某些功能,这些功能是通过完整的函数定义语法获得的。

兰巴舞__name__'<lambda>'

毕竟,Lambda是匿名函数,因此它们不知道自己的名字。

>>> l.__name__
'<lambda>'
>>> foo.__name__
'foo'

因此无法在其命名空间中以编程方式查找lambda。

这限制了某些事情。例如,foo可以使用序列化代码查找,而l不能:

>>> import pickle
>>> pickle.loads(pickle.dumps(l))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7fbbc0464e18>: 
attribute lookup <lambda> on __main__ failed

我们可以foo很好地查找-因为它知道自己的名字:

>>> pickle.loads(pickle.dumps(foo))
<function foo at 0x7fbbbee79268>

Lambda没有注释,也没有文档字符串

基本上没有记录lambda。让我们重写foo一下以便更好地记录下来:

def foo() -> int:
    """a nullary function, returns 0 every time"""
    return 0

现在,foo具有文档:

>>> foo.__annotations__
{'return': <class 'int'>}
>>> help(foo)
Help on function foo in module __main__:

foo() -> int
    a nullary function, returns 0 every time

鉴于我们没有相同的机制为lambda提供相同的信息:

>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda (...)

但是我们可以将它们黑客化:

>>> l.__doc__ = 'nullary -> 0'
>>> l.__annotations__ = {'return': int}
>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda ) -> in
    nullary -> 0

但是,可能会有一些错误弄乱了帮助的输出。

Lambda只能返回一个表达式

Lambda不能返回复杂的语句,只能返回表达式。

>>> lambda: if True: 0
  File "<stdin>", line 1
    lambda: if True: 0
             ^
SyntaxError: invalid syntax

当然,表达式可能会相当复杂,如果您非常努力,则可以使用lambda完成相同的操作,但是增加的复杂性更不利于编写清晰的代码。

我们使用Python来提高清晰度和可维护性。过度使用lambda可以解决这个问题。

Lambda 的唯一优势:可以在单个表达式中创建

这是唯一可能的上行空间。由于可以使用表达式创建lambda,因此可以在函数调用内部创建它。

与在其他位置创建的名称相比,在函数调用内部创建一个函数可以避免(廉价的)名称查找。

但是,由于严格评估了Python,因此除了避免名称查找外,这样做没有其他性能上的提高。

对于一个非常简单的表达式,我可以选择一个lambda。

在做交互式Python时,我也倾向于使用lambdas,以避免在可能的情况下出现多行。当我想在调用时将参数传递给构造函数时,我使用以下代码格式timeit.repeat

import timeit

def return_nullary_lambda(return_value=0):
    return lambda: return_value

def return_nullary_function(return_value=0):
    def nullary_fn():
        return return_value
    return nullary_fn

现在:

>>> min(timeit.repeat(lambda: return_nullary_lambda(1)))
0.24312214995734394
>>> min(timeit.repeat(lambda: return_nullary_function(1)))
0.24894469301216304

我相信微小的时间差以上可以归结为在名称查找return_nullary_function-注意,这是微不足道的。

结论

Lambda非常适合非正式情况,在这种情况下,您希望减少代码行以支持单数点。

Lambda对于更正式的情况是不利的,在这种情况下,您需要为以后将要出现的代码编辑者提供清晰的信息,特别是在它们不平凡的情况下。

我们知道应该给我们的对象起好名字。当对象没有物体时我们该怎么做名称,?

由于所有这些原因,我通常更喜欢使用def代替with 来创建函数lambda

More preferable: lambda functions or nested functions (def)?

There is one advantage to using a lambda over a regular function: they are created in an expression.

There are several drawbacks:

  • no name (just '<lambda>')
  • no docstrings
  • no annotations
  • no complex statements

They are also both the same type of object. For those reasons, I generally prefer to create functions with the def keyword instead of with lambdas.

First point – they’re the same type of object

A lambda results in the same type of object as a regular function

>>> l = lambda: 0
>>> type(l)
<class 'function'>
>>> def foo(): return 0
... 
>>> type(foo)
<class 'function'>
>>> type(foo) is type(l)
True

Since lambdas are functions, they’re first-class objects.

Both lambdas and functions:

  • can be passed around as an argument (same as a regular function)
  • when created within an outer function become a closure over that outer functions’ locals

But lambdas are, by default, missing some things that functions get via full function definition syntax.

A lamba’s __name__ is '<lambda>'

Lambdas are anonymous functions, after all, so they don’t know their own name.

>>> l.__name__
'<lambda>'
>>> foo.__name__
'foo'

Thus lambda’s can’t be looked up programmatically in their namespace.

This limits certain things. For example, foo can be looked up with serialized code, while l cannot:

>>> import pickle
>>> pickle.loads(pickle.dumps(l))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7fbbc0464e18>: 
attribute lookup <lambda> on __main__ failed

We can lookup foo just fine – because it knows its own name:

>>> pickle.loads(pickle.dumps(foo))
<function foo at 0x7fbbbee79268>

Lambdas have no annotations and no docstring

Basically, lambdas are not documented. Let’s rewrite foo to be better documented:

def foo() -> int:
    """a nullary function, returns 0 every time"""
    return 0

Now, foo has documentation:

>>> foo.__annotations__
{'return': <class 'int'>}
>>> help(foo)
Help on function foo in module __main__:

foo() -> int
    a nullary function, returns 0 every time

Whereas, we don’t have the same mechanism to give the same information to lambdas:

>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda (...)

But we can hack them on:

>>> l.__doc__ = 'nullary -> 0'
>>> l.__annotations__ = {'return': int}
>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda ) -> in
    nullary -> 0

But there’s probably some error messing up the output of help, though.

Lambdas can only return an expression

Lambdas can’t return complex statements, only expressions.

>>> lambda: if True: 0
  File "<stdin>", line 1
    lambda: if True: 0
             ^
SyntaxError: invalid syntax

Expressions can admittedly be rather complex, and if you try very hard you can probably accomplish the same with a lambda, but the added complexity is more of a detriment to writing clear code.

We use Python for clarity and maintainability. Overuse of lambdas can work against that.

The only upside for lambdas: can be created in a single expression

This is the only possible upside. Since you can create a lambda with an expression, you can create it inside of a function call.

Creating a function inside a function call avoids the (inexpensive) name lookup versus one created elsewhere.

However, since Python is strictly evaluated, there is no other performance gain to doing so aside from avoiding the name lookup.

For a very simple expression, I might choose a lambda.

I also tend to use lambdas when doing interactive Python, to avoid multiple lines when one will do. I use the following sort of code format when I want to pass in an argument to a constructor when calling timeit.repeat:

import timeit

def return_nullary_lambda(return_value=0):
    return lambda: return_value

def return_nullary_function(return_value=0):
    def nullary_fn():
        return return_value
    return nullary_fn

And now:

>>> min(timeit.repeat(lambda: return_nullary_lambda(1)))
0.24312214995734394
>>> min(timeit.repeat(lambda: return_nullary_function(1)))
0.24894469301216304

I believe the slight time difference above can be attributed to the name lookup in return_nullary_function – note that it is very negligible.

Conclusion

Lambdas are good for informal situations where you want to minimize lines of code in favor of making a singular point.

Lambdas are bad for more formal situations where you need clarity for editors of code who will come later, especially in cases where they are non-trivial.

We know we are supposed to give our objects good names. How can we do so when the object has no name?

For all of these reasons, I generally prefer to create functions with def instead of with lambda.


回答 6

我同意nosklo的建议:如果需要给函数命名,请使用deflambda当我只是将简短的代码片段传递给另一个函数时,我会保留函数,例如:

a = [ (1,2), (3,4), (5,6) ]
b = map( lambda x: x[0]+x[1], a )

I agree with nosklo’s advice: if you need to give the function a name, use def. I reserve lambda functions for cases where I’m just passing a brief snippet of code to another function, e.g.:

a = [ (1,2), (3,4), (5,6) ]
b = map( lambda x: x[0]+x[1], a )

回答 7

在同意其他答案的同时,有时它更具可读性。这是一个lambda方便使用的示例,在用例中,我经常遇到N维defaultdict
这是一个例子:

from collections import defaultdict
d = defaultdict(lambda: defaultdict(list))
d['Foo']['Bar'].append(something)

我发现它比def为第二维创建更具可读性。对于更大的尺寸,这一点更为重要。

While agreeing with the other answers, sometimes it’s more readable. Here’s an example where lambda comes in handy, in a use case I keep encountering of an N dimensional defaultdict.
Here’s an example:

from collections import defaultdict
d = defaultdict(lambda: defaultdict(list))
d['Foo']['Bar'].append(something)

I find it more readable than creating a def for the second dimension. This is even more significant for higher dimensions.


回答 8

lambda的主要用途一直是用于简单的回调函数,以及用于map,reduce,filter,后者需要将函数用作参数。随着列表理解成为规范,并且允许添加,如:

x = [f for f in range(1, 40) if f % 2]

很难想象在日常使用中使用lambda的真实情况。因此,我要避免使用lambda并创建嵌套函数。

The primary use of lambda has always been for simple callback functions, and for map, reduce, filter, which require a function as an argument. With list comprehensions becoming the norm, and the added allowed if as in:

x = [f for f in range(1, 40) if f % 2]

it’s hard to imagine a real case for the use of lambda in daily use. As a result, I’d say, avoid lambda and create nested functions.


回答 9

Lambda的一个重要限制是它们除了表达式外不能包含其他任何内容。一个lambda表达式几乎不可能产生除琐碎的副作用之外的其他任何东西,因为它的身体不能像人体一样富裕。def “ ed函数”。

话虽这么说,Lua影响了我的编程风格,使之广泛地使用了匿名函数,并且我在其中充斥了代码。最重要的是,我倾向于以不考虑列表推导或生成器的方式将map / reduce视为抽象运算符,就像我要通过使用这些运算符明确推迟实现决策一样。

编辑:这是一个很老的问题,我对此事的看法有所改变。

首先,我强烈反对将lambda表达式分配给变量。因为python具有专门的语法(提示,def)。除此之外,lambda的许多用途(即使没有名称)也具有预定义的(且效率更高)的实现。例如,所讨论的示例可以缩写为just (1).__add__,而无需将其包装在a lambda或中def。许多其他常见的用途可以使用的某种组合来满足operatoritertoolsfunctools模块。

An important limitation of lambdas is that they cannot contain anything besides an expression. It’s nearly impossible for a lambda expression to produce anything besides trivial side effects, since it cannot have anywhere near as rich a body as a def‘ed function.

That being said, Lua influenced my programming style toward the extensive use of anonymous functions, and I litter my code with them. On top of that, I tend to think about map/reduce as abstract operators in ways I don’t consider list comprehensions or generators, almost as If I’m deferring an implementation decision explicitly by using those operators.

Edit: This is a pretty old question, and my opinions on the matter have changed, somewhat.

First off, I am strongly biased against assigning a lambda expression to a variable; as python has a special syntax just for that (hint, def). In addition to that, many of the uses for lambda, even when they don’t get a name, have predefined (and more efficient) implementations. For instance, the example in question can be abbreviated to just (1).__add__, without the need to wrap it in a lambda or def. Many other common uses can be satisfied with some combination of the operator, itertools and functools modules.


回答 10

  • 计算时间。
  • 没有名称的功能。
  • 实现一个功能和多个使用功能。

考虑一个简单的例子,

# CREATE ONE FUNCTION AND USE IT TO PERFORM MANY OPERATIONS ON SAME TYPE OF DATA STRUCTURE.
def variousUse(a,b=lambda x:x[0]):
    return [b(i) for i in a]

dummyList = [(0,1,2,3),(4,5,6,7),(78,45,23,43)]
variousUse(dummyList)                           # extract first element
variousUse(dummyList,lambda x:[x[0],x[2],x[3]]) # extract specific indexed element
variousUse(dummyList,lambda x:x[0]+x[2])        # add specific elements
variousUse(dummyList,lambda x:x[0]*x[2])        # multiply specific elements
  • Computation time.
  • Function without name.
  • To achieve One function and many use functionality.

Considering a simple example,

# CREATE ONE FUNCTION AND USE IT TO PERFORM MANY OPERATIONS ON SAME TYPE OF DATA STRUCTURE.
def variousUse(a,b=lambda x:x[0]):
    return [b(i) for i in a]

dummyList = [(0,1,2,3),(4,5,6,7),(78,45,23,43)]
variousUse(dummyList)                           # extract first element
variousUse(dummyList,lambda x:[x[0],x[2],x[3]]) # extract specific indexed element
variousUse(dummyList,lambda x:x[0]+x[2])        # add specific elements
variousUse(dummyList,lambda x:x[0]*x[2])        # multiply specific elements

回答 11

如果仅要将lambda分配给本地范围内的变量,则最好使用def,因为它更具可读性,并且将来可以更轻松地扩展:

fun = lambda a, b: a ** b # a pointless use of lambda
map(fun, someList)

要么

def fun(a, b): return a ** b # more readable
map(fun, someList)

If you are just going to assign the lambda to a variable in the local scope, you may as well use def because it is more readable and can be expanded more easily in the future:

fun = lambda a, b: a ** b # a pointless use of lambda
map(fun, someList)

or

def fun(a, b): return a ** b # more readable
map(fun, someList)

回答 12

我发现的lambda的一种用途是在调试消息中。

由于可以懒惰地评估lambda,因此您可以使用以下代码:

log.debug(lambda: "this is my message: %r" % (some_data,))

而不是可能很昂贵:

log.debug("this is my message: %r" % (some_data,))

即使调试调用由于当前的日志记录级别而没有产生输出,该命令也将处理格式字符串。

当然,要使它按所描述的那样工作,正在使用的日志记录模块必须支持lambda作为“惰性参数”(就像我的日志记录模块一样)。

相同的想法可以应用于按需内容值创建的任何其他惰性评估情况。

例如,此自定义三元运算符:

def mif(condition, when_true, when_false):
    if condition:
         return when_true()
    else:
         return when_false()

mif(a < b, lambda: a + a, lambda: b + b)

代替:

def mif(condition, when_true, when_false):
    if condition:
         return when_true
    else:
         return when_false

mif(a < b, a + a, b + b)

如果使用lambda,则只会评估由条件选择的表达式,而不会评估lambda。

当然,您可以简单地使用函数而不是lambda,但是对于短表达式而言,lambda更精简。

One use for lambdas I have found… is in debug messages.

Since lambdas can be lazily evaluated you can have code like this:

log.debug(lambda: "this is my message: %r" % (some_data,))

instead of possibly expensive:

log.debug("this is my message: %r" % (some_data,))

which processes the format string even if the debug call does not produce output because of current logging level.

Of course for it to work as described the logging module in use must support lambdas as “lazy parameters” (as my logging module does).

The same idea may be applied to any other case of lazy evaluation for on demand content value creation.

For example this custom ternary operator:

def mif(condition, when_true, when_false):
    if condition:
         return when_true()
    else:
         return when_false()

mif(a < b, lambda: a + a, lambda: b + b)

instead of:

def mif(condition, when_true, when_false):
    if condition:
         return when_true
    else:
         return when_false

mif(a < b, a + a, b + b)

with lambdas only the expression selected by the condition will be evaluated, without lambdas both will be evaluated.

Of course you could simply use functions instead of lambdas, but for short expressions lambdas are (c)leaner.


回答 13

我同意nosklo。顺便说一句即使使用一次也扔掉功能,大多数情况下,您只想使用操作员模块中的某些功能。

EG:

您有一个带有此签名的函数:myFunction(data,callback function)。

您想传递一个添加2个元素的函数。

使用lambda:

myFunction(data, (lambda x, y : x + y))

pythonic方式:

import operator
myFunction(data, operator.add)

或当然,这是一个简单的示例,但是操作员模块提供了很多东西,包括用于列表和字典的项目设置器/获取器。真的很酷。

I agree with nosklo. By the way, even with a use once, throw away function, most of the time you just want to use something from the operator module.

E.G :

You have a function with this signature : myFunction(data, callback function).

You want to pass a function that add 2 elements.

Using lambda :

myFunction(data, (lambda x, y : x + y))

The pythonic way :

import operator
myFunction(data, operator.add)

Or course this is a simple example, but there is a lot of stuff the operator module provides, including the items setters / getters for list and dict. Really cool.


回答 14

一个主要的区别是您不能def内联使用函数,我认为这是函数最方便的用例lambda。例如,在对对象列表进行排序时:

my_list.sort(key=lambda o: o.x)

因此,我建议继续使用lambda进行此类琐碎的操作,这些操作也并不能真正受益于功能命名所提供的自动文档。

A major difference is that you can not use def functions inline, which is in my opinion the most convenient use case for a lambda function. For example when sorting a list of objects:

my_list.sort(key=lambda o: o.x)

I would therefore suggest keeping the use of lambdas to this kind of trivial operations, which also do not really benefit from the automatic documentation provided by naming the function.


回答 15

lambda对于生成新函数很有用:

>>> def somefunc(x): return lambda y: x+y
>>> f = somefunc(10)
>>> f(2)
12
>>> f(4)
14

lambda is useful for generating new functions:

>>> def somefunc(x): return lambda y: x+y
>>> f = somefunc(10)
>>> f(2)
12
>>> f(4)
14

提取numpy数组中的特定列

问题:提取numpy数组中的特定列

这是一个简单的问题,但要说我有一个MxN矩阵。我要做的就是提取特定的列并将其存储在另一个numpy数组中,但是我得到了无效的语法错误。这是代码:

extractedData = data[[:,1],[:,9]]. 

似乎上述行就足够了,但我想不是。我环顾四周,但找不到关于此特定场景的任何语法明智的方法。

This is an easy question but say I have an MxN matrix. All I want to do is extract specific columns and store them in another numpy array but I get invalid syntax errors. Here is the code:

extractedData = data[[:,1],[:,9]]. 

It seems like the above line should suffice but I guess not. I looked around but couldn’t find anything syntax wise regarding this specific scenario.


回答 0

我假设你想要的列19?那是

data[:, [1, 9]]

或带有名称:

data[:, ['Column Name1','Column Name2']]

您可以从data.dtype.names… 获得名字。

I assume you wanted columns 1 and 9?

To select multiple columns at once, use

X = data[:, [1, 9]]

To select one at a time, use

x, y = data[:, 1], data[:, 9]

With names:

data[:, ['Column Name1','Column Name2']]

You can get the names from data.dtype.names


回答 1

假设您要获取具有该代码段的第1列和第9列,则应为:

extractedData = data[:,[1,9]]

Assuming you want to get columns 1 and 9 with that code snippet, it should be:

extractedData = data[:,[1,9]]

回答 2

如果只想提取一些列:

idx_IN_columns = [1, 9]
extractedData = data[:,idx_IN_columns]

如果要排除特定列:

idx_OUT_columns = [1, 9]
idx_IN_columns = [i for i in xrange(np.shape(data)[1]) if i not in idx_OUT_columns]
extractedData = data[:,idx_IN_columns]

if you want to extract only some columns:

idx_IN_columns = [1, 9]
extractedData = data[:,idx_IN_columns]

if you want to exclude specific columns:

idx_OUT_columns = [1, 9]
idx_IN_columns = [i for i in xrange(np.shape(data)[1]) if i not in idx_OUT_columns]
extractedData = data[:,idx_IN_columns]

回答 3

我想指出的一件事是,如果要提取的列数为1,则生成的矩阵将不是您期望的Mx1矩阵,而是包含所提取列元素的数组。

要将其转换为矩阵应在结果数组上使用reshape(M,1)方法。

One thing I would like to point out is, if the number of columns you want to extract is 1 the resulting matrix would not be a Mx1 Matrix as you might expect but instead an array containing the elements of the column you extracted.

To convert it to Matrix the reshape(M,1) method should be used on the resulting array.


回答 4

只是:

>>> m = np.matrix(np.random.random((5, 5)))
>>> m
matrix([[0.91074101, 0.65999332, 0.69774588, 0.007355  , 0.33025395],
        [0.11078742, 0.67463754, 0.43158254, 0.95367876, 0.85926405],
        [0.98665185, 0.86431513, 0.12153138, 0.73006437, 0.13404811],
        [0.24602225, 0.66139215, 0.08400288, 0.56769924, 0.47974697],
        [0.25345299, 0.76385882, 0.11002419, 0.2509888 , 0.06312359]])
>>> m[:,[1, 2]]
matrix([[0.65999332, 0.69774588],
        [0.67463754, 0.43158254],
        [0.86431513, 0.12153138],
        [0.66139215, 0.08400288],
        [0.76385882, 0.11002419]])

列不必按顺序排列:

>>> m[:,[2, 1, 3]]
matrix([[0.69774588, 0.65999332, 0.007355  ],
        [0.43158254, 0.67463754, 0.95367876],
        [0.12153138, 0.86431513, 0.73006437],
        [0.08400288, 0.66139215, 0.56769924],
        [0.11002419, 0.76385882, 0.2509888 ]])

Just:

>>> m = np.matrix(np.random.random((5, 5)))
>>> m
matrix([[0.91074101, 0.65999332, 0.69774588, 0.007355  , 0.33025395],
        [0.11078742, 0.67463754, 0.43158254, 0.95367876, 0.85926405],
        [0.98665185, 0.86431513, 0.12153138, 0.73006437, 0.13404811],
        [0.24602225, 0.66139215, 0.08400288, 0.56769924, 0.47974697],
        [0.25345299, 0.76385882, 0.11002419, 0.2509888 , 0.06312359]])
>>> m[:,[1, 2]]
matrix([[0.65999332, 0.69774588],
        [0.67463754, 0.43158254],
        [0.86431513, 0.12153138],
        [0.66139215, 0.08400288],
        [0.76385882, 0.11002419]])

The columns need not to be in order:

>>> m[:,[2, 1, 3]]
matrix([[0.69774588, 0.65999332, 0.007355  ],
        [0.43158254, 0.67463754, 0.95367876],
        [0.12153138, 0.86431513, 0.73006437],
        [0.08400288, 0.66139215, 0.56769924],
        [0.11002419, 0.76385882, 0.2509888 ]])

回答 5

使用类似这样的列表从ND数组中选择列时,您还应该注意一件事:

data[:,:,[1,9]]

如果要删除维度(例如,仅选择一行),则将由于某种原因对结果数组进行置换。所以:

print data.shape            # gives [10,20,30]
selection = data[1,:,[1,9]]
print selection.shape       # gives [2,20] instead of [20,2]!!

One more thing you should pay attention to when selecting columns from N-D array using a list like this:

data[:,:,[1,9]]

If you are removing a dimension (by selecting only one row, for example), the resulting array will be (for some reason) permuted. So:

print data.shape            # gives [10,20,30]
selection = data[1,:,[1,9]]
print selection.shape       # gives [2,20] instead of [20,2]!!

回答 6

您可以使用 :

extracted_data = data.ix[:,['Column1','Column2']]

You can use the following:

extracted_data = data.ix[:,['Column1','Column2']]

回答 7

我认为这里的解决方案不再适用于python版本的更新,为此使用新的python函数的一种方法是:

extracted_data = data[['Column Name1','Column Name2']].to_numpy()

这将为您提供理想的结果。

您可以在此处找到文档:https : //pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html#pandas.DataFrame.to_numpy

I think the solution here is not working with an update of the python version anymore, one way to do it with a new python function for it is:

extracted_data = data[['Column Name1','Column Name2']].to_numpy()

which gives you the desired outcome.

The documentation you can find here: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_numpy.html#pandas.DataFrame.to_numpy


回答 8

您还可以使用extractedData = data([:,1],[:, 9])

you can also use extractedData=data([:,1],[:,9])


为什么([1,0]中的1 = = True)评估为False?

问题:为什么([1,0]中的1 = = True)评估为False?

在查看该问题的答案时,我发现自己不明白自己的答案。

我真的不明白这是如何解析的。为什么第二个示例返回False?

>>> 1 in [1,0]             # This is expected
True
>>> 1 in [1,0] == True     # This is strange
False
>>> (1 in [1,0]) == True   # This is what I wanted it to be
True
>>> 1 in ([1,0] == True)   # But it's not just a precedence issue!
                           # It did not raise an exception on the second example.

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    1 in ([1,0] == True)
TypeError: argument of type 'bool' is not iterable

谢谢你的帮助。我想我一定会错过一些非常明显的东西。


我认为这与链接的重复项有细微的不同:

为什么表达式0 <0 == 0在Python中返回False?

这两个问题都与人类对表达的理解有关。在我看来,似乎有两种评估表达方式的方法。当然,两者都不正确,但是在我的示例中,最后的解释是不可能的。

看着0 < 0 == 0您可以想象每个被评估的部分都可以表达为有意义:

>>> (0 < 0) == 0
True
>>> 0 < (0 == 0)
True

因此,链接回答了为什么这样评估False

>>> 0 < 0 == 0
False

但是,对于我的示例1 in ([1,0] == True),将其作为一个表达式没有任何意义,因此,除了存在两种(公认错误的)可能的解释之外,似乎只有一种可能:

>>> (1 in [1,0]) == True

When I was looking at answers to this question, I found I didn’t understand my own answer.

I don’t really understand how this is being parsed. Why does the second example return False?

>>> 1 in [1,0]             # This is expected
True
>>> 1 in [1,0] == True     # This is strange
False
>>> (1 in [1,0]) == True   # This is what I wanted it to be
True
>>> 1 in ([1,0] == True)   # But it's not just a precedence issue!
                           # It did not raise an exception on the second example.

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    1 in ([1,0] == True)
TypeError: argument of type 'bool' is not iterable

Thanks for any help. I think I must be missing something really obvious.


I think this is subtly different to the linked duplicate:

Why does the expression 0 < 0 == 0 return False in Python?.

Both questions are to do with human comprehension of the expression. There seemed to be two ways (to my mind) of evaluating the expression. Of course neither were correct, but in my example, the last interpretation is impossible.

Looking at 0 < 0 == 0 you could imagine each half being evaluated and making sense as an expression:

>>> (0 < 0) == 0
True
>>> 0 < (0 == 0)
True

So the link answers why this evaluates False:

>>> 0 < 0 == 0
False

But with my example 1 in ([1,0] == True) doesn’t make sense as an expression, so instead of there being two (admittedly wrong) possible interpretations, only one seems possible:

>>> (1 in [1,0]) == True

回答 0

Python实际上在这里应用比较运算符链接。表达式被翻译成

(1 in [1, 0]) and ([1, 0] == True)

这显然是False

类似的表达式也会发生这种情况

a < b < c

转换为

(a < b) and (b < c)

(无需b两次评估)。

有关更多详细信息,请参见Python语言文档

Python actually applies comparison operator chaining here. The expression is translated to

(1 in [1, 0]) and ([1, 0] == True)

which is obviously False.

This also happens for expressions like

a < b < c

which translate to

(a < b) and (b < c)

(without evaluating b twice).

See the Python language documentation for further details.


Python“提高”用法

问题:Python“提高”用法

raiseraise fromPython 和有什么不一样?

try:
    raise ValueError
except Exception as e:
    raise IndexError

产生

Traceback (most recent call last):
  File "tmp.py", line 2, in <module>
    raise ValueError
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tmp.py", line 4, in <module>
    raise IndexError
IndexError

try:
    raise ValueError
except Exception as e:
    raise IndexError from e

产生

Traceback (most recent call last):
  File "tmp.py", line 2, in <module>
    raise ValueError
ValueError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "tmp.py", line 4, in <module>
    raise IndexError from e
IndexError

What’s the difference between raise and raise from in Python?

try:
    raise ValueError
except Exception as e:
    raise IndexError

which yields

Traceback (most recent call last):
  File "tmp.py", line 2, in <module>
    raise ValueError
ValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "tmp.py", line 4, in <module>
    raise IndexError
IndexError

and

try:
    raise ValueError
except Exception as e:
    raise IndexError from e

which yields

Traceback (most recent call last):
  File "tmp.py", line 2, in <module>
    raise ValueError
ValueError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "tmp.py", line 4, in <module>
    raise IndexError from e
IndexError

回答 0

区别在于,当您使用时from,会设置__cause__属性,并且消息会指出异常是由引起的。如果您省略,from__cause__设置no ,但是也可以设置该__context__属性,然后回溯显示上下文,就像处理其他事件时一样

__context__如果raise在异常处理程序中使用过,则设置发生的情况;如果您raise在其他任何地方使用过,则也不会__context__设置。

如果__cause__设置了a,那么__suppress_context__ = True还会在异常上设置一个标志;当__suppress_context__设置为时,在打印回溯时True__context__忽略。

从异常处理程序,你养的时候希望显示上下文(不想处理另一个异常发生时,然后用消息)raise ... from None来设置__suppress_context__True

换句话说,Python 在异常上设置了一个上下文,因此您可以自省引发异常的位置,让您查看是否用它替换了另一个异常。您还可以将原因添加到异常中,使回溯明确地显示其他异常(使用不同的措辞),并且上下文将被忽略(但在调试时仍可以自省)。使用raise ... from None使您可以禁止打印上下文。

请参阅raise语句documenation

from子句用于异常链接:如果给定,则第二个表达式必须是另一个异常类或实例,然后将其作为__cause__属性(可写)附加到引发的异常上。如果未处理引发的异常,则将打印两个异常:

>>> try:
...     print(1 / 0)
... except Exception as exc:
...     raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

如果在异常处理程序或finally子句中引发异常,则类似的机制会隐式工作:然后,将先前的异常附加为新异常的__context__属性:

>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

另请参阅内置异常文档,以获取有关上下文的详细信息,并提供附加到异常的原因信息。

The difference is that when you use from, the __cause__ attribute is set and the message states that the exception was directly caused by. If you omit the from then no __cause__ is set, but the __context__ attribute may be set as well, and the traceback then shows the context as during handling something else happened.

Setting the __context__ happens if you used raise in an exception handler; if you used raise anywhere else no __context__ is set either.

If a __cause__ is set, a __suppress_context__ = True flag is also set on the exception; when __suppress_context__ is set to True, the __context__ is ignored when printing a traceback.

When raising from a exception handler where you don’t want to show the context (don’t want a during handling another exception happened message), then use raise ... from None to set __suppress_context__ to True.

In other words, Python sets a context on exceptions so you can introspect where an exception was raised, letting you see if another exception was replaced by it. You can also add a cause to an exception, making the traceback explicit about the other exception (use different wording), and the context is ignored (but can still be introspected when debugging). Using raise ... from None lets you suppress the context being printed.

See the raise statement documenation:

The from clause is used for exception chaining: if given, the second expression must be another exception class or instance, which will then be attached to the raised exception as the __cause__ attribute (which is writable). If the raised exception is not handled, both exceptions will be printed:

>>> try:
...     print(1 / 0)
... except Exception as exc:
...     raise RuntimeError("Something bad happened") from exc
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

A similar mechanism works implicitly if an exception is raised inside an exception handler or a finally clause: the previous exception is then attached as the new exception’s __context__ attribute:

>>> try:
...     print(1 / 0)
... except:
...     raise RuntimeError("Something bad happened")
...
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: int division or modulo by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
RuntimeError: Something bad happened

Also see the Built-in Exceptions documentation for details on the context and cause information attached to exceptions.


Python:一次尝试多项

问题:Python:一次尝试多项

在Python中,except一个try语句是否可以有多个语句?如 :

try:
 #something1
 #something2
except ExceptionType1:
 #return xyz
except ExceptionType2:
 #return abc

In Python, is it possible to have multiple except statements for one try statement? Such as :

try:
 #something1
 #something2
except ExceptionType1:
 #return xyz
except ExceptionType2:
 #return abc

回答 0

是的,有可能。

try:
   ...
except FirstException:
   handle_first_one()

except SecondException:
   handle_second_one()

except (ThirdException, FourthException, FifthException) as e:
   handle_either_of_3rd_4th_or_5th()

except Exception:
   handle_all_other_exceptions()

请参阅:http : //docs.python.org/tutorial/errors.html

关键字“ as”用于将错误分配给变量,以便稍后可以在代码中更彻底地调查错误。另请注意,在python 3中需要三重异常情况的括号。此页面具有更多信息:在一行中捕获多个异常(块除外)

Yes, it is possible.

try:
   ...
except FirstException:
   handle_first_one()

except SecondException:
   handle_second_one()

except (ThirdException, FourthException, FifthException) as e:
   handle_either_of_3rd_4th_or_5th()

except Exception:
   handle_all_other_exceptions()

See: http://docs.python.org/tutorial/errors.html

The “as” keyword is used to assign the error to a variable so that the error can be investigated more thoroughly later on in the code. Also note that the parentheses for the triple exception case are needed in python 3. This page has more info: Catch multiple exceptions in one line (except block)


什么是“ 1 ..__ truediv__”?Python是否具有..(“点点”)表示法语法?

问题:什么是“ 1 ..__ truediv__”?Python是否具有..(“点点”)表示法语法?

最近,我遇到了一种语法,这种语法在我学习python时从未见过,在大多数教程中,这种..表示法看起来像这样:

f = 1..__truediv__ # or 1..__div__ for python 2

print(f(8)) # prints 0.125 

我发现它和(当然,它更长)完全一样:

f = lambda x: (1).__truediv__(x)
print(f(8)) # prints 0.125 or 1//8

但是我的问题是:

  • 它怎么做呢?
  • 这两个点实际上意味着什么?
  • 如何在更复杂的语句中使用它(如果可能)?

将来可能会为我节省很多代码行… :)

I recently came across a syntax I never seen before when I learned python nor in most tutorials, the .. notation, it looks something like this:

f = 1..__truediv__ # or 1..__div__ for python 2

print(f(8)) # prints 0.125 

I figured it was exactly the same as (except it’s longer, of course):

f = lambda x: (1).__truediv__(x)
print(f(8)) # prints 0.125 or 1//8

But my questions are:

  • How can it do that?
  • What does it actually mean with the two dots?
  • How can you use it in a more complex statement (if possible)?

This will probably save me many lines of code in the future…:)


回答 0

您所拥有的是一个float不带尾随零的文字,然后您可以访问的__truediv__方法。它本身不是运算符;第一个点是float值的一部分,第二个点是用于访问对象属性和方法的点运算符。

您可以通过执行以下操作达到相同的目的。

>>> f = 1.
>>> f
1.0
>>> f.__floordiv__
<method-wrapper '__floordiv__' of float object at 0x7f9fb4dc1a20>

另一个例子

>>> 1..__add__(2.)
3.0

在这里,我们将1.0加到2.0,显然得出3.0。

What you have is a float literal without the trailing zero, which you then access the __truediv__ method of. It’s not an operator in itself; the first dot is part of the float value, and the second is the dot operator to access the objects properties and methods.

You can reach the same point by doing the following.

>>> f = 1.
>>> f
1.0
>>> f.__floordiv__
<method-wrapper '__floordiv__' of float object at 0x7f9fb4dc1a20>

Another example

>>> 1..__add__(2.)
3.0

Here we add 1.0 to 2.0, which obviously yields 3.0.


回答 1

该问题已经得到足够的答案(即@Paul Rooney的答案),但也可以验证这些答案的正确性。

让我回顾一下现有的答案:这..不是一个语法元素!

您可以检查源代码如何“标记化”。这些标记表示代码的解释方式:

>>> from tokenize import tokenize
>>> from io import BytesIO

>>> s = "1..__truediv__"
>>> list(tokenize(BytesIO(s.encode('utf-8')).readline))
[...
 TokenInfo(type=2 (NUMBER), string='1.', start=(1, 0), end=(1, 2), line='1..__truediv__'),
 TokenInfo(type=53 (OP), string='.', start=(1, 2), end=(1, 3), line='1..__truediv__'),
 TokenInfo(type=1 (NAME), string='__truediv__', start=(1, 3), end=(1, 14), line='1..__truediv__'),
 ...]

因此,字符串1.被解释为数字,第二个.是OP(运算符,在这种情况下为“ get attribute”运算符),而则__truediv__是方法名称。因此,这只是访问__truediv__float 的方法1.0

查看生成的字节码的另一种方法是对其进行汇编。这实际上显示了执行某些代码时执行的指令: dis

>>> import dis

>>> def f():
...     return 1..__truediv__

>>> dis.dis(f)
  4           0 LOAD_CONST               1 (1.0)
              3 LOAD_ATTR                0 (__truediv__)
              6 RETURN_VALUE

基本上说的一样。它加载__truediv__常量的属性1.0


关于你的问题

以及如何在更复杂的语句中使用它(如果可能)?

即使您可能永远也不要这样写代码,只是因为不清楚代码在做什么。因此,请不要在更复杂的语句中使用它。我什至会走得更远,以至于您不应该在如此“简单”的语句中使用它,至少您应该使用括号将指令分开:

f = (1.).__truediv__

这肯定会更具可读性-但类似于:

from functools import partial
from operator import truediv
f = partial(truediv, 1.0)

会更好!

使用的方法partial还保留了python的数据模型(该1..__truediv__方法没有!),可以通过以下小片段进行演示:

>>> f1 = 1..__truediv__
>>> f2 = partial(truediv, 1.)

>>> f2(1+2j)  # reciprocal of complex number - works
(0.2-0.4j)
>>> f2('a')   # reciprocal of string should raise an exception
TypeError: unsupported operand type(s) for /: 'float' and 'str'

>>> f1(1+2j)  # reciprocal of complex number - works but gives an unexpected result
NotImplemented
>>> f1('a')   # reciprocal of string should raise an exception but it doesn't
NotImplemented

这是因为1. / (1+2j)不是由- float.__truediv__而是通过complex.__rtruediv__operator.truediv进行评估的,请确保在正常操作返回时调用了反向操作,NotImplemented__truediv__直接操作时没有这些后备。这种“预期行为”的丧失是您(通常)不应直接使用魔术方法的主要原因。

The question is already sufficiently answered (i.e. @Paul Rooneys answer) but it’s also possible to verify the correctness of these answers.

Let me recap the existing answers: The .. is not a single syntax element!

You can check how the source code is “tokenized”. These tokens represent how the code is interpreted:

>>> from tokenize import tokenize
>>> from io import BytesIO

>>> s = "1..__truediv__"
>>> list(tokenize(BytesIO(s.encode('utf-8')).readline))
[...
 TokenInfo(type=2 (NUMBER), string='1.', start=(1, 0), end=(1, 2), line='1..__truediv__'),
 TokenInfo(type=53 (OP), string='.', start=(1, 2), end=(1, 3), line='1..__truediv__'),
 TokenInfo(type=1 (NAME), string='__truediv__', start=(1, 3), end=(1, 14), line='1..__truediv__'),
 ...]

So the string 1. is interpreted as number, the second . is an OP (an operator, in this case the “get attribute” operator) and the __truediv__ is the method name. So this is just accessing the __truediv__ method of the float 1.0.

Another way of viewing the generated bytecode is to disassemble it. This actually shows the instructions that are performed when some code is executed:

>>> import dis

>>> def f():
...     return 1..__truediv__

>>> dis.dis(f)
  4           0 LOAD_CONST               1 (1.0)
              3 LOAD_ATTR                0 (__truediv__)
              6 RETURN_VALUE

Which basically says the same. It loads the attribute __truediv__ of the constant 1.0.


Regarding your question

And how can you use it in a more complex statement (if possible)?

Even though it’s possible you should never write code like that, simply because it’s unclear what the code is doing. So please don’t use it in more complex statements. I would even go so far that you shouldn’t use it in so “simple” statements, at least you should use parenthesis to separate the instructions:

f = (1.).__truediv__

this would be definetly more readable – but something along the lines of:

from functools import partial
from operator import truediv
f = partial(truediv, 1.0)

would be even better!

The approach using partial also preserves python’s data model (the 1..__truediv__ approach does not!) which can be demonstrated by this little snippet:

>>> f1 = 1..__truediv__
>>> f2 = partial(truediv, 1.)

>>> f2(1+2j)  # reciprocal of complex number - works
(0.2-0.4j)
>>> f2('a')   # reciprocal of string should raise an exception
TypeError: unsupported operand type(s) for /: 'float' and 'str'

>>> f1(1+2j)  # reciprocal of complex number - works but gives an unexpected result
NotImplemented
>>> f1('a')   # reciprocal of string should raise an exception but it doesn't
NotImplemented

This is because 1. / (1+2j) is not evaluated by float.__truediv__ but with complex.__rtruediv__operator.truediv makes sure the reverse operation is called when the normal operation returns NotImplemented but you don’t have these fallbacks when you operate on __truediv__ directly. This loss of “expected behaviour” is the main reason why you (normally) shouldn’t use magic methods directly.


回答 2

首先,两个点可能有点尴尬:

f = 1..__truediv__ # or 1..__div__ for python 2

但这与写作相同:

f = 1.0.__truediv__ # or 1.0.__div__ for python 2

因为float文字可以用三种形式编写:

normal_float = 1.0
short_float = 1.  # == 1.0
prefixed_float = .1  # == 0.1

Two dots together may be a little awkward at first:

f = 1..__truediv__ # or 1..__div__ for python 2

But it is the same as writing:

f = 1.0.__truediv__ # or 1.0.__div__ for python 2

Because float literals can be written in three forms:

normal_float = 1.0
short_float = 1.  # == 1.0
prefixed_float = .1  # == 0.1

回答 3

什么f = 1..__truediv__

f是在值为1的float上绑定的特殊方法。特别,

1.0 / x

在Python 3中,调用:

(1.0).__truediv__(x)

证据:

class Float(float):
    def __truediv__(self, other):
        print('__truediv__ called')
        return super(Float, self).__truediv__(other)

和:

>>> one = Float(1)
>>> one/2
__truediv__ called
0.5

如果这样做:

f = one.__truediv__

我们保留绑定到该绑定方法的名称

>>> f(2)
__truediv__ called
0.5
>>> f(3)
__truediv__ called
0.3333333333333333

如果我们在一个紧密的循环中执行该点分查找,则可以节省一些时间。

解析抽象语法树(AST)

我们可以看到,解析表达式的AST可以告诉我们,我们__truediv__在浮点数上获取属性1.0

>>> import ast
>>> ast.dump(ast.parse('1..__truediv__').body[0])
"Expr(value=Attribute(value=Num(n=1.0), attr='__truediv__', ctx=Load()))"

您可以从以下获得相同的结果函数:

f = float(1).__truediv__

要么

f = (1.0).__truediv__

扣除

我们也可以通过扣除到达那里。

让我们建立它。

1本身是一个int

>>> 1
1
>>> type(1)
<type 'int'>

1,之后是句点:

>>> 1.
1.0
>>> type(1.)
<type 'float'>

下一个点本身就是SyntaxError,但它会在float实例上开始点分查找:

>>> 1..__truediv__
<method-wrapper '__truediv__' of float object at 0x0D1C7BF0>

没有人提到这一点 -这现在是浮动的“绑定方法”1.0

>>> f = 1..__truediv__
>>> f
<method-wrapper '__truediv__' of float object at 0x127F3CD8>
>>> f(2)
0.5
>>> f(3)
0.33333333333333331

我们可以更容易地完成相同的功能:

>>> def divide_one_by(x):
...     return 1.0/x
...     
>>> divide_one_by(2)
0.5
>>> divide_one_by(3)
0.33333333333333331

性能

divide_one_by函数的缺点是它需要另一个Python堆栈框架,这使其比绑定方法要慢一些:

>>> def f_1():
...     for x in range(1, 11):
...         f(x)
...         
>>> def f_2():
...     for x in range(1, 11):
...         divide_one_by(x)
...         
>>> timeit.repeat(f_1)
[2.5495760687176485, 2.5585621018805469, 2.5411816588331888]
>>> timeit.repeat(f_2)
[3.479687248616699, 3.46196088706062, 3.473726342237768]

当然,如果您仅可以使用普通文字,那就更快了:

>>> def f_3():
...     for x in range(1, 11):
...         1.0/x
...         
>>> timeit.repeat(f_3)
[2.1224895628296281, 2.1219930218637728, 2.1280188256941983]

What is f = 1..__truediv__?

f is a bound special method on a float with a value of one. Specifically,

1.0 / x

in Python 3, invokes:

(1.0).__truediv__(x)

Evidence:

class Float(float):
    def __truediv__(self, other):
        print('__truediv__ called')
        return super(Float, self).__truediv__(other)

and:

>>> one = Float(1)
>>> one/2
__truediv__ called
0.5

If we do:

f = one.__truediv__

We retain a name bound to that bound method

>>> f(2)
__truediv__ called
0.5
>>> f(3)
__truediv__ called
0.3333333333333333

If we were doing that dotted lookup in a tight loop, this could save a little time.

Parsing the Abstract Syntax Tree (AST)

We can see that parsing the AST for the expression tells us that we are getting the __truediv__ attribute on the floating point number, 1.0:

>>> import ast
>>> ast.dump(ast.parse('1..__truediv__').body[0])
"Expr(value=Attribute(value=Num(n=1.0), attr='__truediv__', ctx=Load()))"

You could get the same resulting function from:

f = float(1).__truediv__

Or

f = (1.0).__truediv__

Deduction

We can also get there by deduction.

Let’s build it up.

1 by itself is an int:

>>> 1
1
>>> type(1)
<type 'int'>

1 with a period after it is a float:

>>> 1.
1.0
>>> type(1.)
<type 'float'>

The next dot by itself would be a SyntaxError, but it begins a dotted lookup on the instance of the float:

>>> 1..__truediv__
<method-wrapper '__truediv__' of float object at 0x0D1C7BF0>

No one else has mentioned this – This is now a “bound method” on the float, 1.0:

>>> f = 1..__truediv__
>>> f
<method-wrapper '__truediv__' of float object at 0x127F3CD8>
>>> f(2)
0.5
>>> f(3)
0.33333333333333331

We could accomplish the same function much more readably:

>>> def divide_one_by(x):
...     return 1.0/x
...     
>>> divide_one_by(2)
0.5
>>> divide_one_by(3)
0.33333333333333331

Performance

The downside of the divide_one_by function is that it requires another Python stack frame, making it somewhat slower than the bound method:

>>> def f_1():
...     for x in range(1, 11):
...         f(x)
...         
>>> def f_2():
...     for x in range(1, 11):
...         divide_one_by(x)
...         
>>> timeit.repeat(f_1)
[2.5495760687176485, 2.5585621018805469, 2.5411816588331888]
>>> timeit.repeat(f_2)
[3.479687248616699, 3.46196088706062, 3.473726342237768]

Of course, if you can just use plain literals, that’s even faster:

>>> def f_3():
...     for x in range(1, 11):
...         1.0/x
...         
>>> timeit.repeat(f_3)
[2.1224895628296281, 2.1219930218637728, 2.1280188256941983]

Python中%的结果是什么?

问题:Python中%的结果是什么?

什么是%在计算?我似乎无法弄清楚它的作用。

例如,它算出计算的百分比4 % 2吗:显然等于0。如何?

What does the % in a calculation? I can’t seem to work out what it does.

Does it work out a percent of the calculation for example: 4 % 2 is apparently equal to 0. How?


回答 0

%(模)运算符从第一个参数除以第二个参数得出余数。首先将数字参数转换为通用类型。零权限参数引发ZeroDivisionError异常。参数可以是浮点数,例如3.14%0.7等于0.34(因为3.14等于4 * 0.7 + 0.34。)模运算符始终产生与第二个操作数具有相同符号的结果(或为零);结果的绝对值严格小于第二个操作数的绝对值[2]。

取自http://docs.python.org/reference/expressions.html

例1: 6%2计算结果为0,如果将6除以2(3次),则没有余数。

实施例27%2评估为1因为有一个的其余部分1时7由2(3次)划分。

综上所述,它返回除法运算的余数,或者0没有余数。因此,6%2意味着找到6的余数除以2。

The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. A zero right argument raises the ZeroDivisionError exception. The arguments may be floating point numbers, e.g., 3.14%0.7 equals 0.34 (since 3.14 equals 4*0.7 + 0.34.) The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand [2].

Taken from http://docs.python.org/reference/expressions.html

Example 1: 6%2 evaluates to 0 because there’s no remainder if 6 is divided by 2 ( 3 times ).

Example 2: 7%2 evaluates to 1 because there’s a remainder of 1 when 7 is divided by 2 ( 3 times ).

So to summarise that, it returns the remainder of a division operation, or 0 if there is no remainder. So 6%2 means find the remainder of 6 divided by 2.


回答 1

在某种程度上,主题%还用于字符串格式化操作,例如%=将值替换为字符串:

>>> x = 'abc_%(key)s_'
>>> x %= {'key':'value'}
>>> x 
'abc_value_'

同样,偏离主题,但它似乎是一个小记录功能,它花了一段时间来跟踪,并且我认为这是有关Python的模数计算的此SO页面高度行列。

Somewhat off topic, the % is also used in string formatting operations like %= to substitute values into a string:

>>> x = 'abc_%(key)s_'
>>> x %= {'key':'value'}
>>> x 
'abc_value_'

Again, off topic, but it seems to be a little documented feature which took me awhile to track down, and I thought it was related to Pythons modulo calculation for which this SO page ranks highly.


回答 2

像这样的表达式x % y求余数x ÷ y-从技术上讲,它是“模数”而不是“提醒”,因此,如果与其他语言%(余数运算符)进行比较,结果可能会有所不同。有一些细微的差异(如果您对实际的结果感兴趣,另请参见“为什么要使用Python的整数分区”)。

优先级与运算符/(除法)和*(乘法)相同。

>>> 9 / 2
4
>>> 9 % 2
1
  • 9除以2等于4。
  • 4乘2是8
  • 9减去8为1-余数。

Python陷阱:取决于您使用的Python版本,%它也是(不建议使用的)字符串插值运算符,因此请注意您是否来自使用自动类型转换的语言(如PHP或JS),在其中使用'12' % 2 + 3合法的表达式: Python,TypeError: not all arguments converted during string formatting这可能会使您感到困惑。

[Python 3更新]

用户n00p评论:

9/2在Python中为4.5。您必须像这样进行整数除法:9 // 2如果要python告诉您除法(4)之后还剩下多少个整个对象。

确切地说,整数除法曾经是Python 2中的默认设置(请注意,这个答案比我的男孩年龄大,这个男孩已经在学校学习,当时2.x是主流):

$ python2.7
Python 2.7.10 (default, Oct  6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4
>>> 9 // 2
4
>>> 9 % 2
1

在现代Python中,9 / 2结果4.5确实是:

$ python3.6
Python 3.6.1 (default, Apr 27 2017, 00:15:59)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4.5
>>> 9 // 2
4
>>> 9 % 2
1

[更新]

用户dahiya_boy在评论会话中询问:

问:能否请您解释原因-11 % 5 = 4-dahiya_boy

这很奇怪吧?如果您使用JavaScript尝试此操作:

> -11 % 5
-1

这是因为在JavaScript %中,它是“余数”运算符,而在Python中,它是“模数”(时钟数学)运算符。

您可以直接从GvR获得解释


编辑-dahiya_boy

在Java和iOS中,-11 % 5 = -1而在python和ruby中-11 % 5 = 4

Paulo Scardine解释了一半的原因,下面是其余的解释

在Java和iOS,%使剩余这意味着,如果你把11%的5 给出了Quotient = 2 and remainder = 1-11%5给出Quotient = -2 and remainder = -1

快速iOS中的示例代码。

但是当我们在python中谈论它时,它给出了时钟模数。及其使用以下公式的工作

mod(a,n) = a - {n * Floor(a/n)}

那就意味着

mod(11,5) = 11 - {5 * Floor(11/5)} => 11 - {5 * 2}

所以, mod(11,5) = 1

mod(-11,5) = -11 - 5 * Floor(11/5) => -11 - {5 * (-3)}

所以, mod(-11,5) = 4

python 3.0中的示例代码。


为什么Python的整数分区

今天(再次)被要求解释为什么Python中的整数除法返回结果的底数,而不是像C一样向零截断。

对于正数,不足为奇:

>>> 5//2
2

但是,如果其中一个操作数是负数,则结果是下限的,即从零舍入(朝负无穷大):

>>> -5//2
-3
>>> 5//-2
-3

这打扰了一些人,但是有一个很好的数学理由。整数除法运算(//)及其兄弟运算,取模运算(%)在一起并满足良好的数学关系(所有变量均为整数):

a/b = q with remainder r

这样

b*q + r = a and 0 <= r < b

(假设a和b> = 0)。

如果要使关系扩展为负a(使b为正),则有两种选择:如果将q截断为零,则r将变为负,因此不变量变为0 <= abs(r)<否则,您可以将q朝负无穷大移动,并且不变保持0 <= r <b。[更新:解决了此问题]

在数学数论中,数学家总是喜欢后一种选择(例如参见Wikipedia)。对于Python,我做出了相同的选择,因为模运算有一些有趣的应用,其中a的符号没有意义。考虑采用POSIX时间戳(自1970年初以来的秒数),并将其转换为一天中的时间。由于一天中有24 * 3600 = 86400秒,因此该计算仅为t%86400。但是,如果我们使用负数来表示1970年之前的时间,则“截断为零”规则将得出毫无意义的结果!使用下限规则,一切正常。

我想到的其他应用程序是计算机图形学中像素位置的计算。我敢肯定还有更多。

顺便说一下,对于负数b,所有事物都翻转了,并且不变式变为:

0 >= r > b.

那么C为什么不这样做呢?在设计C时,硬件可能没有这样做。而且硬件可能不会这样做,因为在最旧的硬件中,负数表示为“符号+幅度”,而不是如今使用的二进制补码表示法(至少对于整数)。我的第一台计算机是Control Data大型机,它使用整数和浮点数的补码。60的模式表示负零!

蒂姆·彼得斯(Tim Peters)知道所有Python的浮点骨架都埋在哪里,对我希望将这些规则扩展到浮点模数表示担忧。他可能是对的。当x是非常小的负数时,truncate-towards-negative-infinity规则会导致x%1.0的精度损失。但这还不足以打破整数模,并且//与之紧密耦合。

PS。请注意,我使用的是//而不是/-这是Python 3语法,并且在Python 2中也允许强调您知道自己正在调用整数除法。Python 2中的/运算符是模棱两可的,因为它对两个整数操作数返回的结果与对int和一个或两个或多个浮点数的返回不同。但这是一个完全独立的故事。参见PEP 238。

由Guido van Rossum发表于9:49 AM

An expression like x % y evaluates to the remainder of x ÷ y – well, technically it is “modulus” instead of “reminder” so results may be different if you are comparing with other languages where % is the remainder operator. There are some subtle differences (if you are interested in the practical consequences see also “Why Python’s Integer Division Floors” bellow).

Precedence is the same as operators / (division) and * (multiplication).

>>> 9 / 2
4
>>> 9 % 2
1
  • 9 divided by 2 is equal to 4.
  • 4 times 2 is 8
  • 9 minus 8 is 1 – the remainder.

Python gotcha: depending on the Python version you are using, % is also the (deprecated) string interpolation operator, so watch out if you are coming from a language with automatic type casting (like PHP or JS) where an expression like '12' % 2 + 3 is legal: in Python it will result in TypeError: not all arguments converted during string formatting which probably will be pretty confusing for you.

[update for Python 3]

User n00p comments:

9/2 is 4.5 in python. You have to do integer division like so: 9//2 if you want python to tell you how many whole objects is left after division(4).

To be precise, integer division used to be the default in Python 2 (mind you, this answer is older than my boy who is already in school and at the time 2.x were mainstream):

$ python2.7
Python 2.7.10 (default, Oct  6 2017, 22:29:07)
[GCC 4.2.1 Compatible Apple LLVM 9.0.0 (clang-900.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4
>>> 9 // 2
4
>>> 9 % 2
1

In modern Python 9 / 2 results 4.5 indeed:

$ python3.6
Python 3.6.1 (default, Apr 27 2017, 00:15:59)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 9 / 2
4.5
>>> 9 // 2
4
>>> 9 % 2
1

[update]

User dahiya_boy asked in the comment session:

Q. Can you please explain why -11 % 5 = 4 – dahiya_boy

This is weird, right? If you try this in JavaScript:

> -11 % 5
-1

This is because in JavaScript % is the “remainder” operator while in Python it is the “modulus” (clock math) operator.

You can get the explanation directly from GvR:


Edit – dahiya_boy

In Java and iOS -11 % 5 = -1 whereas in python and ruby -11 % 5 = 4.

Well half of the reason is explained by the Paulo Scardine, and rest of the explanation is below here

In Java and iOS, % gives the remainder that means if you divide 11 % 5 gives Quotient = 2 and remainder = 1 and -11 % 5 gives Quotient = -2 and remainder = -1.

Sample code in swift iOS.

But when we talk about in python its gives clock modulus. And its work with below formula

mod(a,n) = a - {n * Floor(a/n)}

Thats means,

mod(11,5) = 11 - {5 * Floor(11/5)} => 11 - {5 * 2}

So, mod(11,5) = 1

And

mod(-11,5) = -11 - 5 * Floor(-11/5) => -11 - {5 * (-3)}

So, mod(-11,5) = 4

Sample code in python 3.0.


Why Python’s Integer Division Floors

I was asked (again) today to explain why integer division in Python returns the floor of the result instead of truncating towards zero like C.

For positive numbers, there’s no surprise:

>>> 5//2
2

But if one of the operands is negative, the result is floored, i.e., rounded away from zero (towards negative infinity):

>>> -5//2
-3
>>> 5//-2
-3

This disturbs some people, but there is a good mathematical reason. The integer division operation (//) and its sibling, the modulo operation (%), go together and satisfy a nice mathematical relationship (all variables are integers):

a/b = q with remainder r

such that

b*q + r = a and 0 <= r < b

(assuming a and b are >= 0).

If you want the relationship to extend for negative a (keeping b positive), you have two choices: if you truncate q towards zero, r will become negative, so that the invariant changes to 0 <= abs(r) < otherwise, you can floor q towards negative infinity, and the invariant remains 0 <= r < b. [update: fixed this para]

In mathematical number theory, mathematicians always prefer the latter choice (see e.g. Wikipedia). For Python, I made the same choice because there are some interesting applications of the modulo operation where the sign of a is uninteresting. Consider taking a POSIX timestamp (seconds since the start of 1970) and turning it into the time of day. Since there are 24*3600 = 86400 seconds in a day, this calculation is simply t % 86400. But if we were to express times before 1970 using negative numbers, the “truncate towards zero” rule would give a meaningless result! Using the floor rule it all works out fine.

Other applications I’ve thought of are computations of pixel positions in computer graphics. I’m sure there are more.

For negative b, by the way, everything just flips, and the invariant becomes:

0 >= r > b.

So why doesn’t C do it this way? Probably the hardware didn’t do this at the time C was designed. And the hardware probably didn’t do it this way because in the oldest hardware, negative numbers were represented as “sign + magnitude” rather than the two’s complement representation used these days (at least for integers). My first computer was a Control Data mainframe and it used one’s complement for integers as well as floats. A pattern of 60 ones meant negative zero!

Tim Peters, who knows where all Python’s floating point skeletons are buried, has expressed some worry about my desire to extend these rules to floating point modulo. He’s probably right; the truncate-towards-negative-infinity rule can cause precision loss for x%1.0 when x is a very small negative number. But that’s not enough for me to break integer modulo, and // is tightly coupled to that.

PS. Note that I am using // instead of / — this is Python 3 syntax, and also allowed in Python 2 to emphasize that you know you are invoking integer division. The / operator in Python 2 is ambiguous, since it returns a different result for two integer operands than for an int and a float or two floats. But that’s a totally separate story; see PEP 238.

Posted by Guido van Rossum at 9:49 AM


回答 3

模数是一种数学运算,有时也称为“时钟算术”。我发现将其简单描述为剩余部分会产生误导和混乱,因为它掩盖了它在计算机科学中被大量使用的真正原因。它实际上是用于环绕循环的。

想想时钟:假设您以“军事”时间查看时钟,该时间范围为0:00-23.59。现在,如果您希望每天午夜发生一些事情,那么您希望当前时间mod 24为零:

如果(小时%24 == 0):

您可以想到历史中的所有小时都围绕24小时一圈地循环,并且一天中的当前小时是无限长的mod24。这是一个比余数更深刻的概念,这是一种数学方法处理周期,这在计算机科学中非常重要。它也用于环绕数组,允许您增加索引并使用模数在到达数组末尾后返回到开头。

The modulus is a mathematical operation, sometimes described as “clock arithmetic.” I find that describing it as simply a remainder is misleading and confusing because it masks the real reason it is used so much in computer science. It really is used to wrap around cycles.

Think of a clock: Suppose you look at a clock in “military” time, where the range of times goes from 0:00 – 23.59. Now if you wanted something to happen every day at midnight, you would want the current time mod 24 to be zero:

if (hour % 24 == 0):

You can think of all hours in history wrapping around a circle of 24 hours over and over and the current hour of the day is that infinitely long number mod 24. It is a much more profound concept than just a remainder, it is a mathematical way to deal with cycles and it is very important in computer science. It is also used to wrap around arrays, allowing you to increase the index and use the modulus to wrap back to the beginning after you reach the end of the array.


回答 4

Python-基本运算符
http://www.tutorialspoint.com/python/python_basic_operators.htm

模量-将左操作数除以右操作数并返回余数

a = 10和b = 20

b%a = 0

Python – Basic Operators
http://www.tutorialspoint.com/python/python_basic_operators.htm

Modulus – Divides left hand operand by right hand operand and returns remainder

a = 10 and b = 20

b % a = 0


回答 5

在大多数语言中,%用于模数。Python也不exceptions。

In most languages % is used for modulus. Python is no exception.


回答 6

%Modulo运算符也可以用于打印字符串(就像在C中一样),如Google https://developers.google.com/edu/python/strings上定义的那样。

      # % operator
  text = "%d little pigs come out or I'll %s and %s and %s" % (3, 'huff', 'puff', 'blow down')

这似乎有点题外话,但肯定会有所帮助。

% Modulo operator can be also used for printing strings (Just like in C) as defined on Google https://developers.google.com/edu/python/strings.

      # % operator
  text = "%d little pigs come out or I'll %s and %s and %s" % (3, 'huff', 'puff', 'blow down')

This seems to bit off topic but It will certainly help someone.


回答 7

x % y计算除法的余数x除以y其中的商是一个整数。其余的符号为y


在Python 3上计算得出6.75; 这是因为这样/做是真正的除法,而不是Python 2上的整数除法(默认情况下)(默认情况下)。在Python 2上1 / 4,由于结果舍入为0。

整数除法也可以在Python 3上使用//运算符完成,因此要得到7,可以执行:

3 + 2 + 1 - 5 + 4 % 2 - 1 // 4 + 6

此外,只需添加以下行,即可在Python 2上获得Python样式划分

from __future__ import division

作为每个源文件中的第一条源代码行。

x % y calculates the remainder of the division x divided by y where the quotient is an integer. The remainder has the sign of y.


On Python 3 the calculation yields 6.75; this is because the / does a true division, not integer division like (by default) on Python 2. On Python 2 1 / 4 gives 0, as the result is rounded down.

The integer division can be done on Python 3 too, with // operator, thus to get the 7 as a result, you can execute:

3 + 2 + 1 - 5 + 4 % 2 - 1 // 4 + 6

Also, you can get the Python style division on Python 2, by just adding the line

from __future__ import division

as the first source code line in each source file.


回答 8

模运算符,通常用于整数的余数除法,但在Python中可用于浮点数。

http://docs.python.org/reference/expressions.html

%(模)运算符从第一个参数除以第二个参数得出余数。首先将数字参数转换为通用类型。零权限参数引发ZeroDivisionError异常。参数可以是浮点数,例如3.14%0.7等于0.34(因为3.14等于4 * 0.7 + 0.34。)模运算符始终产生与第二个操作数具有相同符号的结果(或为零);结果的绝对值严格小于第二个操作数的绝对值[2]。

Modulus operator, it is used for remainder division on integers, typically, but in Python can be used for floating point numbers.

http://docs.python.org/reference/expressions.html

The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type. A zero right argument raises the ZeroDivisionError exception. The arguments may be floating point numbers, e.g., 3.14%0.7 equals 0.34 (since 3.14 equals 4*0.7 + 0.34.) The modulo operator always yields a result with the same sign as its second operand (or zero); the absolute value of the result is strictly smaller than the absolute value of the second operand [2].


回答 9

这是一个模运算,除了它是老式的C风格的字符串格式化运算符,而不是模运算。有关详细信息,请参见此处。您将在现有代码中看到很多这样的内容。

It’s a modulo operation, except when it’s an old-fashioned C-style string formatting operator, not a modulo operation. See here for details. You’ll see a lot of this in existing code.


回答 10

此外,还有一个有用的内置函数,称为divmod

divmod(a,b)

使用两个(非复数)数字作为参数,并在使用长除法时返回一对包含其商和余数的数字。

Also, there is a useful built-in function called divmod:

divmod(a, b)

Take two (non complex) numbers as arguments and return a pair of numbers consisting of their quotient and remainder when using long division.


回答 11

意识到

(3 +2 + 1 - 5) + (4 % 2) - (1/4) + 6

如果使用Python 3.4计算,即使带括号的结果也是6.75,而不是7。


而且’/’运算符也不是那么容易理解(python2.7):试试…

- 1/4

1 - 1/4

这里有点题外话,但是在评估上面的表达式时应该考虑:)

Be aware that

(3 +2 + 1 - 5) + (4 % 2) - (1/4) + 6

even with the brackets results in 6.75 instead of 7 if calculated in Python 3.4.


And the ‘/’ operator is not that easy to understand, too (python2.7): try…

- 1/4

1 - 1/4

This is a bit off-topic here, but should be considered when evaluating the above expression :)


回答 12

对于我来说,很难在线找到使用%的特定用例,例如,为什么做分数模除法或负模除法会得出答案呢?希望这有助于澄清如下问题:

模量部门:

模除法返回数学除法运算的余数。这样做如下:

假设我们的股息为5,除数为2,则以下除法运算将等于(等于x):

dividend = 5
divisor = 2

x = 5/2 
  1. 模量计算的第一步是进行整数除法:

    x_int = 5 // 2(Python中的整数除法使用双斜杠)

    x_int = 2

  2. 接下来,x_int的输出乘以除数:

    x_mult = x_int *除数x_mult = 4

  3. 最后,从x_mult中减去股息

    红利-x_mult = 1

  4. 模运算,因此返回1:

    5%2 = 1

申请将模数应用于分数

Example: 2 % 5 

当应用于分数时,模量的计算与上面相同;但是,重要的是要注意,当除数大于被除数时,整数除法将得出零值:

dividend = 2 
divisor = 5

整数除法得出0,而; 因此,当执行上面的步骤3时,将计算分红的值(减去零):

dividend - 0 = 2  —> 2 % 5 = 2 

申请将模数应用于负数

发生地板除法,其中整数除法的值四舍五入到最低整数值:

import math 

x = -1.1
math.floor(-1.1) = -2 

y = 1.1
math.floor = 1

因此,当您进行整数除法时,您可能会得到与预期不同的结果!

将以上步骤应用于以下除数和除数可以说明模量概念:

dividend: -5 
divisor: 2 

步骤1:应用整数除法

x_int = -5 // 2  = -3

步骤2:将整数除法的结果乘以除数

x_mult = x_int * 2 = -6

步骤3:从乘法变量中减去红利,请注意双负数。

dividend - x_mult = -5 -(-6) = 1

因此:

-5 % 2 = 1

It was hard for me to readily find specific use cases for the use of % online ,e.g. why does doing fractional modulus division or negative modulus division result in the answer that it does. Hope this helps clarify questions like this:

Modulus Division In General:

Modulus division returns the remainder of a mathematical division operation. It is does it as follows:

Say we have a dividend of 5 and divisor of 2, the following division operation would be (equated to x):

dividend = 5
divisor = 2

x = 5/2 
  1. The first step in the modulus calculation is to conduct integer division:

    x_int = 5 // 2 ( integer division in python uses double slash)

    x_int = 2

  2. Next, the output of x_int is multiplied by the divisor:

    x_mult = x_int * divisor x_mult = 4

  3. Lastly, the dividend is subtracted from the x_mult

    dividend – x_mult = 1

  4. The modulus operation ,therefore, returns 1:

    5 % 2 = 1

Application to apply the modulus to a fraction

Example: 2 % 5 

The calculation of the modulus when applied to a fraction is the same as above; however, it is important to note that the integer division will result in a value of zero when the divisor is larger than the dividend:

dividend = 2 
divisor = 5

The integer division results in 0 whereas the; therefore, when step 3 above is performed, the value of the dividend is carried through (subtracted from zero):

dividend - 0 = 2  —> 2 % 5 = 2 

Application to apply the modulus to a negative

Floor division occurs in which the value of the integer division is rounded down to the lowest integer value:

import math 

x = -1.1
math.floor(-1.1) = -2 

y = 1.1
math.floor = 1

Therefore, when you do integer division you may get a different outcome than you expect!

Applying the steps above on the following dividend and divisor illustrates the modulus concept:

dividend: -5 
divisor: 2 

Step 1: Apply integer division

x_int = -5 // 2  = -3

Step 2: Multiply the result of the integer division by the divisor

x_mult = x_int * 2 = -6

Step 3: Subtract the dividend from the multiplied variable, notice the double negative.

dividend - x_mult = -5 -(-6) = 1

Therefore:

-5 % 2 = 1

回答 13

%(模)运算符从第一个参数除以第二个参数得出余数。首先将数字参数转换为通用类型。

3 + 2 + 1-5 + 4%2-1/4 + 6 = 7

这基于运算符优先级。

The % (modulo) operator yields the remainder from the division of the first argument by the second. The numeric arguments are first converted to a common type.

3 + 2 + 1 – 5 + 4 % 2 – 1 / 4 + 6 = 7

This is based on operator precedence.


回答 14

%3 % 2 = 14 % 2 = 0

/ 是(在这种情况下为整数)除,因此:

3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6
1 + 4%2 - 1/4 + 6
1 + 0 - 0 + 6
7

% is modulo. 3 % 2 = 1, 4 % 2 = 0

/ is (an integer in this case) division, so:

3 + 2 + 1 - 5 + 4 % 2 - 1 / 4 + 6
1 + 4%2 - 1/4 + 6
1 + 0 - 0 + 6
7

回答 15

这是模运算 http://en.wikipedia.org/wiki/Modulo_operation

http://docs.python.org/reference/expressions.html

因此,按照操作顺序,

(3 + 2 + 1-5)+(4%2)-(1/4)+ 6

(1)+(0)-(0)+ 6

7

1/4 = 0,因为我们在这里进行整数运算。

It’s a modulo operation http://en.wikipedia.org/wiki/Modulo_operation

http://docs.python.org/reference/expressions.html

So with order of operations, that works out to

(3+2+1-5) + (4%2) – (1/4) + 6

(1) + (0) – (0) + 6

7

The 1/4=0 because we’re doing integer math here.


回答 16

就像许多类似C的语言一样,它是余数或模运算。有关数字类型信息,请参见文档-int,float,long,complex

It is, as in many C-like languages, the remainder or modulo operation. See the documentation for numeric types — int, float, long, complex.


回答 17

模数-左操作数除以右操作数,并返回余数。

如果有帮助:

1:0> 2%6
=> 2
2:0> 8%6
=> 2
3:0> 2%6 == 8%6
=> true

… 等等。

Modulus – Divides left hand operand by right hand operand and returns remainder.

If it helps:

1:0> 2%6
=> 2
2:0> 8%6
=> 2
3:0> 2%6 == 8%6
=> true

… and so on.


回答 18

我发现掌握模数运算符(%)的最简单方法是进行长除法。它是余数,可用于确定数字是偶数还是奇数:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

I have found that the easiest way to grasp the modulus operator (%) is through long division. It is the remainder and can be useful in determining a number to be even or odd:

4%2 = 0

  2
2|4
 -4
  0


11%3 = 2

  3
3|11
 -9
  2

Python字符串中的u前缀是什么?

问题:Python字符串中的u前缀是什么?

像:

u'Hello'

我的猜测是它表示“ Unicode”,对吗?

如果可以,那么什么时候可用?

Like in:

u'Hello'

My guess is that it indicates “Unicode”, is it correct?

If so, since when is it available?


回答 0

您说得对,请参阅3.1.3。Unicode字符串

自Python 2.0以来就是语法。

Python 3使它们多余,因为默认的字符串类型是Unicode。从3.0到3.2版本删除了它们,但是在3.3+重新添加了它们,以便与Python 2兼容,以辅助2到3过渡。

You’re right, see 3.1.3. Unicode Strings.

It’s been the syntax since Python 2.0.

Python 3 made them redundant, as the default string type is Unicode. Versions 3.0 through 3.2 removed them, but they were re-added in 3.3+ for compatibility with Python 2 to aide the 2 to 3 transition.


回答 1

u in u'Some String'表示您的字符串是Unicode字符串

问:我很着急,很可怕,我从Google搜索登陆了。我正在尝试将此数据写入文件,但出现错误,并且此刻我需要最简单的,可能有缺陷的解决方案。

答:您应该真正阅读Joel的“ 绝对最低要求”,每个软件开发人员绝对,肯定必须了解有关字符集的Unicode和字符集(无借口!)文章。

问:请不要输入时间码

A:很好。尝试str('Some String')'Some String'.encode('ascii', 'ignore')。但是,你真的应该读一些答案和讨论上转换Unicode字符串这个优秀,卓越,底漆上的字符编码。

The u in u'Some String' means that your string is a Unicode string.

Q: I’m in a terrible, awful hurry and I landed here from Google Search. I’m trying to write this data to a file, I’m getting an error, and I need the dead simplest, probably flawed, solution this second.

A: You should really read Joel’s Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) essay on character sets.

Q: sry no time code pls

A: Fine. try str('Some String') or 'Some String'.encode('ascii', 'ignore'). But you should really read some of the answers and discussion on Converting a Unicode string and this excellent, excellent, primer on character encoding.


回答 2

我的猜测是它表示“ Unicode”,对吗?

是。

如果可以,那么什么时候可用?

Python2.x。

在Python 3.x中,默认情况下,字符串使用Unicode,并且不需要u前缀。注意:在Python 3.0-3.2中,u是语法错误。在Python 3.3以上版本中,再次简化编写2/3兼容应用程序是合法的。

My guess is that it indicates “Unicode”, is it correct?

Yes.

If so, since when is it available?

Python 2.x.

In Python 3.x the strings use Unicode by default and there’s no need for the u prefix. Note: in Python 3.0-3.2, the u is a syntax error. In Python 3.3+ it’s legal again to make it easier to write 2/3 compatible apps.


回答 3

我来这里是因为我的requests输出中有滑稽字符综合症。我以为response.text会给我一个正确解码的字符串,但是在输出中我发现了有趣的双字符,应该是德国变音符。

原来response.encoding是空的,所以response不知道如何正确解码内容,只是将其视为ASCII(我猜)。

我的解决方案是使用“ response.content”获取原始字节并手动对其应用decode('utf_8')。结果是舍恩·乌姆劳特(schöneUmlaute)。

正确解码

毛皮

与不正确解码

Ăź

I came here because I had funny-char-syndrome on my requests output. I thought response.text would give me a properly decoded string, but in the output I found funny double-chars where German umlauts should have been.

Turns out response.encoding was empty somehow and so response did not know how to properly decode the content and just treated it as ASCII (I guess).

My solution was to get the raw bytes with ‘response.content’ and manually apply decode('utf_8') to it. The result was schöne Umlaute.

The correctly decoded

für

vs. the improperly decoded

fĂźr


回答 4

供人类使用的所有字符串都应使用u“”。

我发现以下心态在处理Python字符串时有很大帮助:所有 Python清单字符串都应使用u""语法。该""语法仅适用于字节数组。

在扑打开始之前,让我解释一下。大多数Python程序开始于使用"" for字符串。但是随后他们需要从Internet上支持文档,因此他们开始使用它"".decode,突然之间,到处都有关于解码该内容的异常-都是由于使用""了字符串。在这种情况下,Unicode的确像病毒一样,将造成严重破坏。

但是,如果您遵循我的规则,就不会感染这种病毒(因为您已经被感染了)。

All strings meant for humans should use u””.

I found that the following mindset helps a lot when dealing with Python strings: All Python manifest strings should use the u"" syntax. The "" syntax is for byte arrays, only.

Before the bashing begins, let me explain. Most Python programs start out with using "" for strings. But then they need to support documentation off the Internet, so they start using "".decode and all of a sudden they are getting exceptions everywhere about decoding this and that – all because of the use of "" for strings. In this case, Unicode does act like a virus and will wreak havoc.

But, if you follow my rule, you won’t have this infection (because you will already be infected).


回答 5

它是Unicode。

只需将变量放在之间str(),它将正常工作。

但是,如果您有两个类似以下的列表:

a = ['co32','co36']
b = [u'co32',u'co36']

如果选中set(a)==set(b),它将显示为False,但是如果执行以下操作:

b = str(b)
set(a)==set(b)

现在,结果将为True。

It’s Unicode.

Just put the variable between str(), and it will work fine.

But in case you have two lists like the following:

a = ['co32','co36']
b = [u'co32',u'co36']

If you check set(a)==set(b), it will come as False, but if you do as follows:

b = str(b)
set(a)==set(b)

Now, the result will be True.