分类目录归档:知识问答

用于除法时,“ /”和“ //”之间有什么区别?

问题:用于除法时,“ /”和“ //”之间有什么区别?

将一个使用在另一个上是否有好处?在Python 2中,它们似乎都返回相同的结果:

>>> 6/3
2
>>> 6//3
2

Is there a benefit to using one over the other? In Python 2, they both seem to return the same results:

>>> 6/3
2
>>> 6//3
2

回答 0

在Python 3.x中,5 / 2将返回2.5并且5 // 2将返回2。前者是浮点除法,后者是地板除法,有时也称为整数除法

在Python 2.2或更高版本的2.x行中,除非执行from __future__ import division,否则整数没有区别,这会使Python 2.x采取3.x行为。

不管将来的进口是什么,5.0 // 2都会归还,2.0因为这是操作的地板分割结果。

您可以在https://docs.python.org/whatsnew/2.2.html#pep-238-changing-the-division-operator中找到详细说明

In Python 3.x, 5 / 2 will return 2.5 and 5 // 2 will return 2. The former is floating point division, and the latter is floor division, sometimes also called integer division.

In Python 2.2 or later in the 2.x line, there is no difference for integers unless you perform a from __future__ import division, which causes Python 2.x to adopt the 3.x behavior.

Regardless of the future import, 5.0 // 2 will return 2.0 since that’s the floor division result of the operation.

You can find a detailed description at https://docs.python.org/whatsnew/2.2.html#pep-238-changing-the-division-operator


回答 1

Python 2.x澄清:

为了阐明Python 2.x系列,/既不是楼层划分也不是真正的划分。当前接受的答案尚不清楚。

/是地板除法时 ARG游戏int,但真正当师之一或两者的参数的个数是float

上面讲了更多的事实,并且比接受的答案中的第二段更清楚。

Python 2.x Clarification:

To clarify for the Python 2.x line, / is neither floor division nor true division. The current accepted answer is not clear on this.

/ is floor division when both args are int, but is true division when either or both of the args are float.

The above tells more truth, and is more clear than the 2nd paragraph in the accepted answer.


回答 2

//不论您使用哪种类型,都可以实施“楼层划分”。所以 1.0/2.0会给0.5,但两者1/21//2并且1.0//2.0会给0

有关详细信息,请参见https://docs.python.org/whatsnew/2.2.html#pep-238-changing-the-division-operator

// implements “floor division”, regardless of your type. So 1.0/2.0 will give 0.5, but both 1/2, 1//2 and 1.0//2.0 will give 0.

See https://docs.python.org/whatsnew/2.2.html#pep-238-changing-the-division-operator for details


回答 3

// -浮点除法

// ->楼层划分

让我们在python 2.7和python 3.5中查看一些示例。

Python 2.7.10和Python 3.5

print (2/3)  ----> 0                   Python 2.7
print (2/3)  ----> 0.6666666666666666  Python 3.5

Python 2.7.10和Python 3.5

  print (4/2)  ----> 2         Python 2.7
  print (4/2)  ----> 2.0       Python 3.5

现在,如果您希望在python 2.7中具有与python 3.5相同的输出,则可以执行以下操作:

Python 2.7.10

from __future__ import division
print (2/3)  ----> 0.6666666666666666   #Python 2.7
print (4/2)  ----> 2.0                  #Python 2.7

在python 2.7和python 3.5中,Floor划分之间没有区别

138.93//3 ---> 46.0        #Python 2.7
138.93//3 ---> 46.0        #Python 3.5
4//3      ---> 1           #Python 2.7
4//3      ---> 1           #Python 3.5

/ –> Floating point division

// –> Floor division

Lets see some examples in both python 2.7 and in Python 3.5.

Python 2.7.10 vs. Python 3.5

print (2/3)  ----> 0                   Python 2.7
print (2/3)  ----> 0.6666666666666666  Python 3.5

Python 2.7.10 vs. Python 3.5

  print (4/2)  ----> 2         Python 2.7
  print (4/2)  ----> 2.0       Python 3.5

Now if you want to have (in python 2.7) same output as in python 3.5, you can do the following:

Python 2.7.10

from __future__ import division
print (2/3)  ----> 0.6666666666666666   #Python 2.7
print (4/2)  ----> 2.0                  #Python 2.7

Where as there is no differece between Floor division in both python 2.7 and in Python 3.5

138.93//3 ---> 46.0        #Python 2.7
138.93//3 ---> 46.0        #Python 3.5
4//3      ---> 1           #Python 2.7
4//3      ---> 1           #Python 3.5

回答 4

正如大家已经回答的那样,//是楼层划分。

之所以如此重要,是因为//在所有2.2版本的Python版本中,包括Python 3.x版本,都明确地进行了地域划分。

的行为/可能会有所不同,具体取决于:

  • 是否有效__future__导入(模块本地)
  • Python命令行选项,-Q old或者-Q new

As everyone has already answered, // is floor division.

Why this is important is that // is unambiguously floor division, in all Python versions from 2.2, including Python 3.x versions.

The behavior of / can change depending on:

  • Active __future__ import or not (module-local)
  • Python command line option, either -Q old or -Q new

回答 5

>>> print 5.0 / 2
2.5

>>> print 5.0 // 2
2.0
>>> print 5.0 / 2
2.5

>>> print 5.0 // 2
2.0

回答 6

Python 2.7和其他即将发布的python版本:

  • 部门(/

将左操作数除以右操作数

例: 4 / 2 = 2

  • 楼层部门(//

操作数的除法,结果是除掉小数点后的数字的商。但是,如果其中一个操作数是负数,则结果是下限的,即从零开始舍入(朝负无穷大):

例如:9//2 = 49.0//2.0 = 4.0-11//3 = -4-11.0//3 = -4.0

这两个/师和//地板除法运算的操作以类似的方式。

Python 2.7 and other upcoming version of python:

  • Division (/)

Divides left hand operand by right hand operand

Example: 4 / 2 = 2

  • Floor Division (//)

The division of operands where the result is the quotient in which the digits after the decimal point are removed. But if one of the operands is negative, the result is floored, i.e., rounded away from zero (towards negative infinity):

Examples: 9//2 = 4 and 9.0//2.0 = 4.0, -11//3 = -4, -11.0//3 = -4.0

Both / Division and // floor division operator are operating in similar fashion.


回答 7

双斜线//是地板分割:

>>> 7//3
2

The double slash, //, is floor division:

>>> 7//3
2

回答 8

//是底数除法,它将始终为您提供结果的整数底数。另一个是“常规”划分。

// is floor division, it will always give you the integer floor of the result. The other is ‘regular’ division.


回答 9

等式的答案四舍五入为下一个较小的整数,或者以.0作为小数点进行浮点运算。

>>>print 5//2
2
>>> print 5.0//2
2.0
>>>print 5//2.0
2.0
>>>print 5.0//2.0
2.0

The answer of the equation is rounded to the next smaller integer or float with .0 as decimal point.

>>>print 5//2
2
>>> print 5.0//2
2.0
>>>print 5//2.0
2.0
>>>print 5.0//2.0
2.0

回答 10

上面的答案是好的。我想补充一点。最多两个值都导致相同的商。在该楼层之后,除法运算符(//)正常工作,但除法运算符()无效/

 - > int(755349677599789174/2)
 - > 377674838799894592      #wrong answer
 - > 755349677599789174 //2
 - > 377674838799894587      #correct answer

The above answers are good. I want to add another point. Up to some values both of them result in the same quotient. After that floor division operator (//) works fine but not division (/) operator.

 - > int(755349677599789174/2)
 - > 377674838799894592      #wrong answer
 - > 755349677599789174 //2
 - > 377674838799894587      #correct answer

回答 11

5.0//2会导致2.0,而不是2因为运算符返回值的返回类型//遵循python强制(类型转换)规则。

Python促进将较低数据类型(整数)转换为较高数据类型(浮点数),以避免数据丢失。

5.0//2 results in 2.0, and not 2 because the return type of the return value from // operator follows python coercion (type casting) rules.

Python promotes conversion of lower datatype (integer) to higher data type (float) to avoid data loss.


回答 12

  • // 是底数划分,它将始终为您提供结果的底数。
  • 另一个/是浮点除法。

以下是之间的差///; 我已经在Python 3.7.2中运行了这些算术运算

>>> print (11 / 3)
3.6666666666666665

>>> print (11 // 3)
3

>>> print (11.3 / 3)
3.7666666666666667

>>> print (11.3 // 3)
3.0
  • // is floor division, it will always give you the floor value of the result.
  • And the other one / is the floating-point division.

Followings are the difference between / and //; I have run these arithmetic operations in Python 3.7.2

>>> print (11 / 3)
3.6666666666666665

>>> print (11 // 3)
3

>>> print (11.3 / 3)
3.7666666666666667

>>> print (11.3 // 3)
3.0

Python3中的StringIO

问题:Python3中的StringIO

我正在使用Python 3.2.1,但无法导入StringIO模块。我使用 io.StringIO和它的作品,但我不能使用它numpygenfromtxt是这样的:

x="1 3\n 4.5 8"        
numpy.genfromtxt(io.StringIO(x))

我收到以下错误:

TypeError: Can't convert 'bytes' object to str implicitly  

当我写的import StringIO时候说

ImportError: No module named 'StringIO'

I am using Python 3.2.1 and I can’t import the StringIO module. I use io.StringIO and it works, but I can’t use it with numpy‘s genfromtxt like this:

x="1 3\n 4.5 8"        
numpy.genfromtxt(io.StringIO(x))

I get the following error:

TypeError: Can't convert 'bytes' object to str implicitly  

and when I write import StringIO it says

ImportError: No module named 'StringIO'

回答 0

当我写导入StringIO时,它说没有这样的模块。

Python 3.0的新功能开始

StringIOcStringIO模块都没有了。而是导入io 模块,分别将io.StringIOio.BytesIO用于文本和数据。


修复一些Python 2代码以使其在Python 3(caveat emptor)中工作的可能有用的方法:

try:
    from StringIO import StringIO ## for Python 2
except ImportError:
    from io import StringIO ## for Python 3

注意:此示例可能与问题的主要内容相切,仅作为一般性地解决缺失StringIO模块时要考虑的内容。 有关消息的更直接解决方案TypeError: Can't convert 'bytes' object to str implicitly,请参阅此答案

when i write import StringIO it says there is no such module.

From What’s New In Python 3.0:

The StringIO and cStringIO modules are gone. Instead, import the io module and use io.StringIO or io.BytesIO for text and data respectively.

.


A possibly useful method of fixing some Python 2 code to also work in Python 3 (caveat emptor):

try:
    from StringIO import StringIO ## for Python 2
except ImportError:
    from io import StringIO ## for Python 3

Note: This example may be tangential to the main issue of the question and is included only as something to consider when generically addressing the missing StringIO module. For a more direct solution the the message TypeError: Can't convert 'bytes' object to str implicitly, see this answer.


回答 1

就我而言,我使用了:

from io import StringIO

In my case I have used:

from io import StringIO

回答 2

在Python 3上,numpy.genfromtxt期望字节流。使用以下内容:

numpy.genfromtxt(io.BytesIO(x.encode()))

On Python 3 numpy.genfromtxt expects a bytes stream. Use the following:

numpy.genfromtxt(io.BytesIO(x.encode()))

回答 3

谢谢OP的问题,以及Roman的回答。我不得不花点时间找到它。希望以下内容对其他人有所帮助。

Python 2.7

请参阅:https//docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html

import numpy as np
from StringIO import StringIO

data = "1, abc , 2\n 3, xxx, 4"

print type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", dtype="|S3", autostrip=True)
"""
[['1' 'abc' '2']
 ['3' 'xxx' '4']]
"""

print '\n', type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

Python 3.5:

import numpy as np
from io import StringIO
import io

data = "1, abc , 2\n 3, xxx, 4"
#print(data)
"""
1, abc , 2
 3, xxx, 4
"""

#print(type(data))
"""
<class 'str'>
"""

#np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
# TypeError: Can't convert 'bytes' object to str implicitly

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", dtype="|S3", autostrip=True))
"""
[[b'1' b'abc' b'2']
 [b'3' b'xxx' b'4']]
"""

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", autostrip=True))
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

在旁边:

dtype =“ | Sx”,其中x = {1,2,3,…}中的任何一个:

dtypes。Python中S1和S2之间的区别

“ | S1和| S2字符串是数据类型描述符;第一个意味着数组保存长度为1的字符串,第二个长度为2。…”

Thank you OP for your question, and Roman for your answer. I had to search a bit to find this; I hope the following helps others.

Python 2.7

See: https://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html

import numpy as np
from StringIO import StringIO

data = "1, abc , 2\n 3, xxx, 4"

print type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", dtype="|S3", autostrip=True)
"""
[['1' 'abc' '2']
 ['3' 'xxx' '4']]
"""

print '\n', type(data)
"""
<type 'str'>
"""

print '\n', np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

Python 3.5:

import numpy as np
from io import StringIO
import io

data = "1, abc , 2\n 3, xxx, 4"
#print(data)
"""
1, abc , 2
 3, xxx, 4
"""

#print(type(data))
"""
<class 'str'>
"""

#np.genfromtxt(StringIO(data), delimiter=",", autostrip=True)
# TypeError: Can't convert 'bytes' object to str implicitly

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", dtype="|S3", autostrip=True))
"""
[[b'1' b'abc' b'2']
 [b'3' b'xxx' b'4']]
"""

print('\n')
print(np.genfromtxt(io.BytesIO(data.encode()), delimiter=",", autostrip=True))
"""
[[  1.  nan   2.]
 [  3.  nan   4.]]
"""

Aside:

dtype=”|Sx”, where x = any of { 1, 2, 3, …}:

dtypes. Difference between S1 and S2 in Python

“The |S1 and |S2 strings are data type descriptors; the first means the array holds strings of length 1, the second of length 2. …”


回答 4

您可以从六个模块中使用StringIO

import six
import numpy

x = "1 3\n 4.5 8"
numpy.genfromtxt(six.StringIO(x))

You can use the StringIO from the six module:

import six
import numpy

x = "1 3\n 4.5 8"
numpy.genfromtxt(six.StringIO(x))

回答 5

Roman Shapovalov的代码应该在Python 3.x和2.6 / 2.7中都可以使用。这里还是完整的示例:

import io
import numpy
x = "1 3\n 4.5 8"
numpy.genfromtxt(io.BytesIO(x.encode()))

输出:

array([[ 1. ,  3. ],
       [ 4.5,  8. ]])

Python 3.x的说明:

  • numpy.genfromtxt 接受字节流(将类似文件的对象解释为字节而不是Unicode)。
  • io.BytesIO 接受字节字符串并返回字节流。 io.StringIO另一方面,将采用Unicode字符串并返回Unicode流。
  • x 被分配了一个字符串文字,在Python 3.x中是Unicode字符串。
  • encode()x提取Unicode字符串并从中取出一个字节字符串,从而提供io.BytesIO有效的参数。

Python 2.6 / 2.7的唯一区别是它x是一个字节字符串(假定from __future__ import unicode_literals未使用),然后encode()获取该字节字符串,x并仍然从中提取相同的字节字符串。因此结果是相同的。


由于这是SO最受欢迎的问题之一,因此StringIO,这里有一些有关import语句和不同Python版本的更多说明。

以下是采用字符串并返回流的类:

  • io.BytesIO(Python 2.6、2.7和3.x)-接收一个字节字符串。返回字节流。
  • io.StringIO(Python 2.6、2.7和3.x)-采用Unicode字符串。返回Unicode流。
  • StringIO.StringIO(Python 2.x)-接受字节字符串或Unicode字符串。如果为字节字符串,则返回字节流。如果是Unicode字符串,则返回Unicode流。
  • cStringIO.StringIO(Python 2.x)-的更快版本StringIO.StringIO,但不能采用包含非ASCII字符的Unicode字符串。

请注意,StringIO.StringIO导入为from StringIO import StringIO,然后用作StringIO(...)。要么这样做,要么您执行import StringIO然后使用StringIO.StringIO(...)。模块名称和类名称恰好是相同的。这类似于datetime这种方式。

使用什么,取决于您支持的Python版本:

  • 如果您仅支持Python 3.x:只需使用io.BytesIOio.StringIO取决于您使用的是哪种数据。

  • 如果您同时支持Python 2.6 / 2.7和3.x,或者正尝试将代码从2.6 / 2.7转换到3.x:最简单的选择仍然是使用io.BytesIOio.StringIO。尽管它StringIO.StringIO很灵活,因此在2.6 / 2.7中似乎是首选,但这种灵活性可能会掩盖3.x版本中将出现的错误。例如,我有一些使用StringIO.StringIOio.StringIO取决于Python版本的代码,但实际上是传递一个字节字符串,因此当我在Python 3.x中进行测试时,它失败了,必须加以修复。

    使用的另一个优点io.StringIO是对通用换行符的支持。如果你传递关键字参数newline=''io.StringIO,这将是能够在任何的分割线\n\r\n\r。我发现那StringIO.StringIO会绊倒\r尤其严重。

    请注意,如果您导入BytesIOStringIOsix,你StringIO.StringIO在Python 2.x和相应的类从io在Python 3.x的 如果您同意我之前的评估,实际上这是应该避免的一种情况,而应该six从中io引入。

  • 如果您支持Python 2.5或更低版本和3.x:您将需要StringIO.StringIO2.5或更低版本,因此您最好使用six。但是要意识到,同时支持2.5和3.x通常非常困难,因此,如果可能的话,应该考虑将最低支持的版本提高到2.6。

Roman Shapovalov’s code should work in Python 3.x as well as Python 2.6/2.7. Here it is again with the complete example:

import io
import numpy
x = "1 3\n 4.5 8"
numpy.genfromtxt(io.BytesIO(x.encode()))

Output:

array([[ 1. ,  3. ],
       [ 4.5,  8. ]])

Explanation for Python 3.x:

  • numpy.genfromtxt takes a byte stream (a file-like object interpreted as bytes instead of Unicode).
  • io.BytesIO takes a byte string and returns a byte stream. io.StringIO, on the other hand, would take a Unicode string and and return a Unicode stream.
  • x gets assigned a string literal, which in Python 3.x is a Unicode string.
  • encode() takes the Unicode string x and makes a byte string out of it, thus giving io.BytesIO a valid argument.

The only difference for Python 2.6/2.7 is that x is a byte string (assuming from __future__ import unicode_literals is not used), and then encode() takes the byte string x and still makes the same byte string out of it. So the result is the same.


Since this is one of SO’s most popular questions regarding StringIO, here’s some more explanation on the import statements and different Python versions.

Here are the classes which take a string and return a stream:

  • io.BytesIO (Python 2.6, 2.7, and 3.x) – Takes a byte string. Returns a byte stream.
  • io.StringIO (Python 2.6, 2.7, and 3.x) – Takes a Unicode string. Returns a Unicode stream.
  • StringIO.StringIO (Python 2.x) – Takes a byte string or Unicode string. If byte string, returns a byte stream. If Unicode string, returns a Unicode stream.
  • cStringIO.StringIO (Python 2.x) – Faster version of StringIO.StringIO, but can’t take Unicode strings which contain non-ASCII characters.

Note that StringIO.StringIO is imported as from StringIO import StringIO, then used as StringIO(...). Either that, or you do import StringIO and then use StringIO.StringIO(...). The module name and class name just happen to be the same. It’s similar to datetime that way.

What to use, depending on your supported Python versions:

  • If you only support Python 3.x: Just use io.BytesIO or io.StringIO depending on what kind of data you’re working with.

  • If you support both Python 2.6/2.7 and 3.x, or are trying to transition your code from 2.6/2.7 to 3.x: The easiest option is still to use io.BytesIO or io.StringIO. Although StringIO.StringIO is flexible and thus seems preferred for 2.6/2.7, that flexibility could mask bugs that will manifest in 3.x. For example, I had some code which used StringIO.StringIO or io.StringIO depending on Python version, but I was actually passing a byte string, so when I got around to testing it in Python 3.x it failed and had to be fixed.

    Another advantage of using io.StringIO is the support for universal newlines. If you pass the keyword argument newline='' into io.StringIO, it will be able to split lines on any of \n, \r\n, or \r. I found that StringIO.StringIO would trip up on \r in particular.

    Note that if you import BytesIO or StringIO from six, you get StringIO.StringIO in Python 2.x and the appropriate class from io in Python 3.x. If you agree with my previous paragraphs’ assessment, this is actually one case where you should avoid six and just import from io instead.

  • If you support Python 2.5 or lower and 3.x: You’ll need StringIO.StringIO for 2.5 or lower, so you might as well use six. But realize that it’s generally very difficult to support both 2.5 and 3.x, so you should consider bumping your lowest supported version to 2.6 if at all possible.


回答 6

为了使此处的示例可 与Python 3.5.2一起使用,可以重写如下:

import io
data =io.BytesIO(b"1, 2, 3\n4, 5, 6") 
import numpy
numpy.genfromtxt(data, delimiter=",")

进行更改的原因可能是文件的内容以数据(字节)为单位,除非经过某种方式解码,否则它们不会生成文本。genfrombytes可能比genfromtxt

In order to make examples from here work with Python 3.5.2, you can rewrite as follows :

import io
data =io.BytesIO(b"1, 2, 3\n4, 5, 6") 
import numpy
numpy.genfromtxt(data, delimiter=",")

The reason for the change may be that the content of a file is in data (bytes) which do not make text until being decoded somehow. genfrombytes may be a better name than genfromtxt.


回答 7

尝试这个

从StringIO导入StringIO

x =“ 1 3 \ n 4.5 8”

numpy.genfromtxt(StringIO(x))

try this

from StringIO import StringIO

x=”1 3\n 4.5 8″

numpy.genfromtxt(StringIO(x))


查找列表的平均值

问题:查找列表的平均值

我必须在Python中找到列表的平均值。到目前为止,这是我的代码

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print reduce(lambda x, y: x + y, l)

我已经知道了,所以它可以将列表中的值加在一起,但是我不知道如何将其划分为它们?

I have to find the average of a list in Python. This is my code so far

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print reduce(lambda x, y: x + y, l)

I’ve got it so it adds together the values in the list, but I don’t know how to make it divide into them?


回答 0

在Python 3.4+上,您可以使用 statistics.mean()

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import statistics
statistics.mean(l)  # 20.11111111111111

在旧版本的Python上,您可以执行

sum(l) / len(l)

在Python 2上,您需要转换len为浮点数才能进行浮点数除法

sum(l) / float(len(l))

无需使用reduce。它慢得多,并在Python 3 中删除

On Python 3.4+ you can use statistics.mean()

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import statistics
statistics.mean(l)  # 20.11111111111111

On older versions of Python you can do

sum(l) / len(l)

On Python 2 you need to convert len to a float to get float division

sum(l) / float(len(l))

There is no need to use reduce. It is much slower and was removed in Python 3.


回答 1

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
sum(l) / len(l)
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
sum(l) / len(l)

回答 2

您可以使用numpy.mean

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import numpy as np
print(np.mean(l))

You can use numpy.mean:

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

import numpy as np
print(np.mean(l))

回答 3

一个统计模块已经加入到了Python 3.4。它具有计算平均值的功能,称为均值。您提供的列表的示例为:

from statistics import mean
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
mean(l)

A statistics module has been added to python 3.4. It has a function to calculate the average called mean. An example with the list you provided would be:

from statistics import mean
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
mean(l)

回答 4

reduce()当Python具有完美的sum()功能时,为什么要使用此功能?

print sum(l) / float(len(l))

float()必须强制Python执行浮点除法。)

Why would you use reduce() for this when Python has a perfectly cromulent sum() function?

print sum(l) / float(len(l))

(The float() is necessary to force Python to do a floating-point division.)


回答 5

如果您使用的是python> = 3.4,则有一个统计资料库

https://docs.python.org/3/library/statistics.html

您可以使用这种卑鄙的方法。假设您有一个要查找均值的数字列表:-

list = [11, 13, 12, 15, 17]
import statistics as s
s.mean(list)

它还有其他方法,如stdev,方差,众数,谐波均值,中位数等,这些方法也非常有用。

There is a statistics library if you are using python >= 3.4

https://docs.python.org/3/library/statistics.html

You may use it’s mean method like this. Let’s say you have a list of numbers of which you want to find mean:-

list = [11, 13, 12, 15, 17]
import statistics as s
s.mean(list)

It has other methods too like stdev, variance, mode, harmonic mean, median etc which are too useful.


回答 6

除了将其强制转换为浮点数外,还可以在总和上加上0.0:

def avg(l):
    return sum(l, 0.0) / len(l)

Instead of casting to float, you can add 0.0 to the sum:

def avg(l):
    return sum(l, 0.0) / len(l)

回答 7

sum(l) / float(len(l)) 是正确的答案,但仅出于完整性考虑,您可以通过一次减少来计算平均值:

>>> reduce(lambda x, y: x + y / float(len(l)), l, 0)
20.111111111111114

请注意,这可能会导致轻微的舍入错误:

>>> sum(l) / float(len(l))
20.111111111111111

sum(l) / float(len(l)) is the right answer, but just for completeness you can compute an average with a single reduce:

>>> reduce(lambda x, y: x + y / float(len(l)), l, 0)
20.111111111111114

Note that this can result in a slight rounding error:

>>> sum(l) / float(len(l))
20.111111111111111

回答 8

我尝试使用上面的选项,但是没有用。尝试这个:

from statistics import mean

n = [11, 13, 15, 17, 19]

print(n)
print(mean(n))

在python 3.5上工作

I tried using the options above but didn’t work. Try this:

from statistics import mean

n = [11, 13, 15, 17, 19]

print(n)
print(mean(n))

worked on python 3.5


回答 9

或使用pandasSeries.mean方法:

pd.Series(sequence).mean()

演示:

>>> import pandas as pd
>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> pd.Series(l).mean()
20.11111111111111
>>> 

从文档:

Series.mean(axis=None, skipna=None, level=None, numeric_only=None, **kwargs)

这是文档:

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.mean.html

以及整个文档:

https://pandas.pydata.org/pandas-docs/stable/10min.html

Or use pandas‘s Series.mean method:

pd.Series(sequence).mean()

Demo:

>>> import pandas as pd
>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> pd.Series(l).mean()
20.11111111111111
>>> 

From the docs:

Series.mean(axis=None, skipna=None, level=None, numeric_only=None, **kwargs)

And here is the docs for this:

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.Series.mean.html

And the whole documentation:

https://pandas.pydata.org/pandas-docs/stable/10min.html


回答 10

在Udacity的问题中,我也有类似的问题要解决。我编码的不是内置函数:

def list_mean(n):

    summing = float(sum(n))
    count = float(len(n))
    if n == []:
        return False
    return float(summing/count)

比平常更长的时间,但是对于初学者来说,这是一个很大的挑战。

I had a similar question to solve in a Udacity´s problems. Instead of a built-in function i coded:

def list_mean(n):

    summing = float(sum(n))
    count = float(len(n))
    if n == []:
        return False
    return float(summing/count)

Much more longer than usual but for a beginner its quite challenging.


回答 11

作为一个初学者,我只是编写了这样的代码:

L = [15, 18, 2, 36, 12, 78, 5, 6, 9]

total = 0

def average(numbers):
    total = sum(numbers)
    total = float(total)
    return total / len(numbers)

print average(L)

as a beginner, I just coded this:

L = [15, 18, 2, 36, 12, 78, 5, 6, 9]

total = 0

def average(numbers):
    total = sum(numbers)
    total = float(total)
    return total / len(numbers)

print average(L)

回答 12

如果您想获得的不仅仅是平均值(也就是平均值),您可以查看scipy统计信息

from scipy import stats
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(stats.describe(l))

# DescribeResult(nobs=9, minmax=(2, 78), mean=20.11111111111111, 
# variance=572.3611111111111, skewness=1.7791785448425341, 
# kurtosis=1.9422716419666397)

If you wanted to get more than just the mean (aka average) you might check out scipy stats

from scipy import stats
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(stats.describe(l))

# DescribeResult(nobs=9, minmax=(2, 78), mean=20.11111111111111, 
# variance=572.3611111111111, skewness=1.7791785448425341, 
# kurtosis=1.9422716419666397)

回答 13

为了reduce用于获得运行平均值,您需要跟踪总数,但也要跟踪到目前为止看到的元素总数。由于这不是列表中的琐碎元素,因此您还必须传递reduce一个额外的参数以使其折叠。

>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> running_average = reduce(lambda aggr, elem: (aggr[0] + elem, aggr[1]+1), l, (0.0,0))
>>> running_average[0]
(181.0, 9)
>>> running_average[0]/running_average[1]
20.111111111111111

In order to use reduce for taking a running average, you’ll need to track the total but also the total number of elements seen so far. since that’s not a trivial element in the list, you’ll also have to pass reduce an extra argument to fold into.

>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> running_average = reduce(lambda aggr, elem: (aggr[0] + elem, aggr[1]+1), l, (0.0,0))
>>> running_average[0]
(181.0, 9)
>>> running_average[0]/running_average[1]
20.111111111111111

回答 14

两者都可以为您提供接近整数或至少10个十进制值的相似值。但是,如果您真正考虑的是长浮点值,则两者可能会有所不同。方法可能因您要实现的目标而异。

>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> print reduce(lambda x, y: x + y, l) / len(l)
20
>>> sum(l)/len(l)
20

浮动值

>>> print reduce(lambda x, y: x + y, l) / float(len(l))
20.1111111111
>>> print sum(l)/float(len(l))
20.1111111111

@安德鲁·克拉克(Andrew Clark)的发言是正确的。

Both can give you close to similar values on an integer or at least 10 decimal values. But if you are really considering long floating values both can be different. Approach can vary on what you want to achieve.

>>> l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
>>> print reduce(lambda x, y: x + y, l) / len(l)
20
>>> sum(l)/len(l)
20

Floating values

>>> print reduce(lambda x, y: x + y, l) / float(len(l))
20.1111111111
>>> print sum(l)/float(len(l))
20.1111111111

@Andrew Clark was correct on his statement.


回答 15

假设

x = [[-5.01,-5.43,1.08,0.86,-2.67,4.94,-2.51,-2.25,5.56,1.03], [-8.12,-3.48,-5.52,-3.78,0.63,3.29,2.09,-2.13,2.86,-3.33], [-3.68,-3.54,1.66,-4.11,7.39,2.08,-2.59,-6.94,-2.26,4.33]]

您会注意到它的x尺寸为3 * 10,如果您需要mean进入每一行,则可以键入

theMean = np.mean(x1,axis=1)

别忘了 import numpy as np

suppose that

x = [[-5.01,-5.43,1.08,0.86,-2.67,4.94,-2.51,-2.25,5.56,1.03], [-8.12,-3.48,-5.52,-3.78,0.63,3.29,2.09,-2.13,2.86,-3.33], [-3.68,-3.54,1.66,-4.11,7.39,2.08,-2.59,-6.94,-2.26,4.33]]

you can notice that x has dimension 3*10 if you need to get the mean to each row you can type this

theMean = np.mean(x1,axis=1)

don’t forget to import numpy as np


回答 16

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

l = map(float,l)
print '%.2f' %(sum(l)/len(l))
l = [15, 18, 2, 36, 12, 78, 5, 6, 9]

l = map(float,l)
print '%.2f' %(sum(l)/len(l))

回答 17

使用以下PYTHON代码在列表中查找平均值:

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(sum(l)//len(l))

试试这个很容易。

Find the average in list By using the following PYTHON code:

l = [15, 18, 2, 36, 12, 78, 5, 6, 9]
print(sum(l)//len(l))

try this it easy.


回答 18

print reduce(lambda x, y: x + y, l)/(len(l)*1.0)

或喜欢以前发布的

sum(l)/(len(l)*1.0)

1.0是确保获得浮点除法

print reduce(lambda x, y: x + y, l)/(len(l)*1.0)

or like posted previously

sum(l)/(len(l)*1.0)

The 1.0 is to make sure you get a floating point division


回答 19

结合以上几个答案,我提出了以下与reduce一起使用的方法,并且不假定您在reduce L函数中可用:

from operator import truediv

L = [15, 18, 2, 36, 12, 78, 5, 6, 9]

def sum_and_count(x, y):
    try:
        return (x[0] + y, x[1] + 1)
    except TypeError:
        return (x + y, 2)

truediv(*reduce(sum_and_count, L))

# prints 
20.11111111111111

Combining a couple of the above answers, I’ve come up with the following which works with reduce and doesn’t assume you have L available inside the reducing function:

from operator import truediv

L = [15, 18, 2, 36, 12, 78, 5, 6, 9]

def sum_and_count(x, y):
    try:
        return (x[0] + y, x[1] + 1)
    except TypeError:
        return (x + y, 2)

truediv(*reduce(sum_and_count, L))

# prints 
20.11111111111111

回答 20

我想添加另一种方法

import itertools,operator
list(itertools.accumulate(l,operator.add)).pop(-1) / len(l)

I want to add just another approach

import itertools,operator
list(itertools.accumulate(l,operator.add)).pop(-1) / len(l)

回答 21

numbers = [0,1,2,3]

numbers[0] = input("Please enter a number")

numbers[1] = input("Please enter a second number")

numbers[2] = input("Please enter a third number")

numbers[3] = input("Please enter a fourth number")

print (numbers)

print ("Finding the Avarage")

avarage = int(numbers[0]) + int(numbers[1]) + int(numbers[2]) + int(numbers [3]) / 4

print (avarage)
numbers = [0,1,2,3]

numbers[0] = input("Please enter a number")

numbers[1] = input("Please enter a second number")

numbers[2] = input("Please enter a third number")

numbers[3] = input("Please enter a fourth number")

print (numbers)

print ("Finding the Avarage")

avarage = int(numbers[0]) + int(numbers[1]) + int(numbers[2]) + int(numbers [3]) / 4

print (avarage)

范围规则的简短描述?

问题:范围规则的简短描述?

Python范围规则到底是什么?

如果我有一些代码:

code1
class Foo:
   code2
   def spam.....
      code3
      for code4..:
       code5
       x()

在哪里x找到?一些可能的选择包括以下列表:

  1. 在随附的源文件中
  2. 在类命名空间中
  3. 在函数定义中
  4. 在for循环中,索引变量
  5. 在for循环内

当函数spam传递到其他地方时,执行期间还会有上下文。也许lambda函数传递的方式有所不同?

某个地方必须有一个简单的参考或算法。对于中级Python程序员而言,这是一个令人困惑的世界。

What exactly are the Python scoping rules?

If I have some code:

code1
class Foo:
   code2
   def spam.....
      code3
      for code4..:
       code5
       x()

Where is x found? Some possible choices include the list below:

  1. In the enclosing source file
  2. In the class namespace
  3. In the function definition
  4. In the for loop index variable
  5. Inside the for loop

Also there is the context during execution, when the function spam is passed somewhere else. And maybe lambda functions pass a bit differently?

There must be a simple reference or algorithm somewhere. It’s a confusing world for intermediate Python programmers.


回答 0

实际上,这是学习Python的第3条关于Python范围解析的简明规则埃德 。(这些规则特定于变量名,而不是属性。如果不加句点引用,则适用这些规则。)

LEGB规则

  • L ocal —在函数(deflambda)中以任何方式分配的名称,但未在该函数中声明为全局

  • E nclosing-function —在任何和所有静态封装函数(deflambda)的本地范围内从内部到外部分配的名称

  • ģ叶形(模块) -在模块文件的顶层分配名称,或通过执行global在声明def文件中

  • : – uilt式(Python)的名称在内置模块的名称预先分配的openrangeSyntaxError,等

因此,在

code1
class Foo:
    code2
    def spam():
        code3
        for code4:
            code5
            x()

for循环中没有自己的名字空间。按照LEGB顺序,范围为

  • L:本地的def spam(在code3code4code5
  • E:任何封闭函数(如果整个示例都在另一个示例中def
  • G:x模块中的全局中是否有任何声明code1
  • B:任何内置x的Python。

x永远不会被发现code2(即使您可能会期望,也请参阅Antti的答案此处)。

Actually, a concise rule for Python Scope resolution, from Learning Python, 3rd. Ed.. (These rules are specific to variable names, not attributes. If you reference it without a period, these rules apply.)

LEGB Rule

  • Local — Names assigned in any way within a function (def or lambda), and not declared global in that function

  • Enclosing-function — Names assigned in the local scope of any and all statically enclosing functions (def or lambda), from inner to outer

  • Global (module) — Names assigned at the top-level of a module file, or by executing a global statement in a def within the file

  • Built-in (Python) — Names preassigned in the built-in names module: open, range, SyntaxError, etc

So, in the case of

code1
class Foo:
    code2
    def spam():
        code3
        for code4:
            code5
            x()

The for loop does not have its own namespace. In LEGB order, the scopes would be

  • L: Local in def spam (in code3, code4, and code5)
  • E: Any enclosing functions (if the whole example were in another def)
  • G: Were there any x declared globally in the module (in code1)?
  • B: Any builtin x in Python.

x will never be found in code2 (even in cases where you might expect it would, see Antti’s answer or here).


回答 1

本质上,Python中唯一引入新作用域的就是函数定义。类是一种特殊情况,因为直接在主体中定义的所有内容都放置在类的命名空间中,但是不能从它们包含的方法(或嵌套类)中直接访问它们。

在您的示例中,只有3个范围可以在其中搜索x:

  • 垃圾邮件的范围-包含在code3和code5(以及code4,循环变量)中定义的所有内容

  • 全局范围-包含code1中定义的所有内容以及Foo(及其后的所有更改)

  • 内置命名空间。有点特殊的情况-它包含各种Python内置函数和类型,例如len()和str()。通常,不应由任何用户代码对此进行修改,因此希望它包含标准功能,而不包含其他任何功能。

仅当您在图片中引入嵌套函数(或lambda)时,才会出现更多作用域。但是,它们的行为几乎与您期望的一样。嵌套函数可以访问本地作用域中的所有内容以及封闭函数的作用域中的任何内容。例如。

def foo():
    x=4
    def bar():
        print x  # Accesses x from foo's scope
    bar()  # Prints 4
    x=5
    bar()  # Prints 5

限制条件:

可以访问除局部函数的变量之外的范围中的变量,但是如果没有进一步的语法,则不能将其反弹到新参数。相反,赋值将创建一个新的局部变量,而不是影响父作用域中的变量。例如:

global_var1 = []
global_var2 = 1

def func():
    # This is OK: It's just accessing, not rebinding
    global_var1.append(4) 

    # This won't affect global_var2. Instead it creates a new variable
    global_var2 = 2 

    local1 = 4
    def embedded_func():
        # Again, this doen't affect func's local1 variable.  It creates a 
        # new local variable also called local1 instead.
        local1 = 5
        print local1

    embedded_func() # Prints 5
    print local1    # Prints 4

为了在功能范围内实际修改全局变量的绑定,需要使用global关键字指定变量是全局变量。例如:

global_var = 4
def change_global():
    global global_var
    global_var = global_var + 1

当前,对于封闭函数范围中的变量,没有任何方法可以做到,但是Python 3引入了一个新关键字“ nonlocal”,它的作用与全局变量类似,但对于嵌套函数范围而言。

Essentially, the only thing in Python that introduces a new scope is a function definition. Classes are a bit of a special case in that anything defined directly in the body is placed in the class’s namespace, but they are not directly accessible from within the methods (or nested classes) they contain.

In your example there are only 3 scopes where x will be searched in:

  • spam’s scope – containing everything defined in code3 and code5 (as well as code4, your loop variable)

  • The global scope – containing everything defined in code1, as well as Foo (and whatever changes after it)

  • The builtins namespace. A bit of a special case – this contains the various Python builtin functions and types such as len() and str(). Generally this shouldn’t be modified by any user code, so expect it to contain the standard functions and nothing else.

More scopes only appear when you introduce a nested function (or lambda) into the picture. These will behave pretty much as you’d expect however. The nested function can access everything in the local scope, as well as anything in the enclosing function’s scope. eg.

def foo():
    x=4
    def bar():
        print x  # Accesses x from foo's scope
    bar()  # Prints 4
    x=5
    bar()  # Prints 5

Restrictions:

Variables in scopes other than the local function’s variables can be accessed, but can’t be rebound to new parameters without further syntax. Instead, assignment will create a new local variable instead of affecting the variable in the parent scope. For example:

global_var1 = []
global_var2 = 1

def func():
    # This is OK: It's just accessing, not rebinding
    global_var1.append(4) 

    # This won't affect global_var2. Instead it creates a new variable
    global_var2 = 2 

    local1 = 4
    def embedded_func():
        # Again, this doen't affect func's local1 variable.  It creates a 
        # new local variable also called local1 instead.
        local1 = 5
        print local1

    embedded_func() # Prints 5
    print local1    # Prints 4

In order to actually modify the bindings of global variables from within a function scope, you need to specify that the variable is global with the global keyword. Eg:

global_var = 4
def change_global():
    global global_var
    global_var = global_var + 1

Currently there is no way to do the same for variables in enclosing function scopes, but Python 3 introduces a new keyword, “nonlocal” which will act in a similar way to global, but for nested function scopes.


回答 2

关于Python3时间,还没有详尽的答案,所以我在这里做了一个答案。4.2.2 Python 3文档名称解析详细介绍了此处描述的大部分内容。

如其他答案中所提供的,本地,封闭,全局和内置有4个基本范围,即LEGB。除此以外,还有一个特殊的范围,即类主体,它不包含该类中定义的方法的封闭范围;类主体内的任何赋值都会使变量从此绑定到类主体中。

特别是,除了和之外,没有块语句创建变量作用域。在Python 2中,列表推导不会创建变量作用域,但是在Python 3中,列表推导内的循环变量是在新作用域中创建的。defclass

证明Class机构的特殊性

x = 0
class X(object):
    y = x
    x = x + 1 # x is now a variable
    z = x

    def method(self):
        print(self.x) # -> 1
        print(x)      # -> 0, the global x
        print(y)      # -> NameError: global name 'y' is not defined

inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)

因此,与函数主体不同,您可以在类主体中将变量重新分配给相同的名称,以获得具有相同名称的类变量。对该名称的进一步查找将解析为class变量。


对于Python的许多新手来说,最大的惊喜之一就是for循环不会创建变量作用域。在Python 2中,列表推导也不创建作用域(而generator和dict则创建!)而是泄漏函数或全局范围中的值:

>>> [ i for i in range(5) ]
>>> i
4

理解可以用作在Python 2中的lambda表达式内创建可修改变量的一种狡猾(或者如果您愿意的话)的方法-lambda表达式确实会创建变量作用域,就像该def语句那样,但是在lambda中不允许使用任何语句。赋值是Python中的语句,表示不允许在lambda中进行变量赋值,但列表推导是一个表达式…

此行为已在Python 3中修复-没有理解表达式或生成器会泄漏变量。


全局实际上意味着模块范围;主要的python模块是__main__; 所有导入的模块都可以通过该sys.modules变量访问;获得__main__可以使用的权限sys.modules['__main__'],或import __main__; 在那里访问和分配属性是完全可以接受的;它们将作为变量显示在主模块的全局范围内。


如果在当前作用域中分配了名称(在类作用域中除外),则该名称将被视为属于该作用域,否则将被视为属于任何分配给该变量的封闭作用域(可能未分配)然而,或者根本没有),或者最后是全球范围。如果该变量被认为是局部变量,但尚未设置或已被删除,则读取变量值将导致UnboundLocalError,这是的子类NameError

x = 5
def foobar():
    print(x)  # causes UnboundLocalError!
    x += 1    # because assignment here makes x a local variable within the function

# call the function
foobar()

作用域可以声明它要使用global关键字明确修改全局变量(模块作用域):

x = 5
def foobar():
    global x
    print(x)
    x += 1

foobar() # -> 5
print(x) # -> 6

即使它被封闭在范围内,这也是可能的:

x = 5
y = 13
def make_closure():
    x = 42
    y = 911
    def func():
        global x # sees the global value
        print(x, y)
        x += 1

    return func

func = make_closure()
func()      # -> 5 911
print(x, y) # -> 6 13

在python 2中,没有简单的方法可以在封闭范围内修改值;通常,这是通过具有可变值(例如长度为1的列表)来模拟的

def make_closure():
    value = [0]
    def get_next_value():
        value[0] += 1
        return value[0]

    return get_next_value

get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2

但是,在python 3中,nonlocal可以进行救援:

def make_closure():
    value = 0
    def get_next_value():
        nonlocal value
        value += 1
        return value
    return get_next_value

get_next = make_closure() # identical behavior to the previous example.

nonlocal文件

与在全局语句中列出的名称不同,非本地语句中列出的名称必须引用封闭范围内的现有绑定(不能明确确定应在其中创建新绑定的范围)。

即,nonlocal始终是指已绑定名称的最内层外部非全局范围(即,分配给该全局for变量,包括在with子句中或用作函数参数,包括用作目标变量)。


任何不被认为是当前作用域或任何封闭作用域局部变量的变量都是全局变量。在模块全局词典中查找全局名称;如果找不到,则从内建模块中查找全局变量;模块的名称从python 2更改为python 3; 在python 2中曾经是__builtin__,在python 3中现在被称为builtins。如果分配给buildins模块的属性,此后它将以可读的全局变量的形式对任何模块可见,除非该模块用自己的同名全局变量来遮盖它们。


读取内置模块也很有用;假设您希望在文件的某些部分使用python 3样式的打印功能,但文件的其他部分仍使用该print语句。在Python 2.6-2.7中,您可以使用以下命令来掌握Python 3 print函数:

import __builtin__

print3 = __builtin__.__dict__['print']

from __future__ import print_function实际上不会导入print功能,随时随地在Python 2 -而不是它只是禁止解析规则,print在当前模块中的语句,处理print像任何其他变量标识符,从而使print功能的内建进行查找。

There was no thorough answer concerning Python3 time, so I made an answer here. Most of what is described here is detailed in the 4.2.2 Resolution of names of the Python 3 documentation.

As provided in other answers, there are 4 basic scopes, the LEGB, for Local, Enclosing, Global and Builtin. In addition to those, there is a special scope, the class body, which does not comprise an enclosing scope for methods defined within the class; any assignments within the class body make the variable from there on be bound in the class body.

Especially, no block statement, besides def and class, create a variable scope. In Python 2 a list comprehension does not create a variable scope, however in Python 3 the loop variable within list comprehensions is created in a new scope.

To demonstrate the peculiarities of the class body

x = 0
class X(object):
    y = x
    x = x + 1 # x is now a variable
    z = x

    def method(self):
        print(self.x) # -> 1
        print(x)      # -> 0, the global x
        print(y)      # -> NameError: global name 'y' is not defined

inst = X()
print(inst.x, inst.y, inst.z, x) # -> (1, 0, 1, 0)

Thus unlike in function body, you can reassign the variable to the same name in class body, to get a class variable with the same name; further lookups on this name resolve to the class variable instead.


One of the greater surprises to many newcomers to Python is that a for loop does not create a variable scope. In Python 2 the list comprehensions do not create a scope either (while generators and dict comprehensions do!) Instead they leak the value in the function or the global scope:

>>> [ i for i in range(5) ]
>>> i
4

The comprehensions can be used as a cunning (or awful if you will) way to make modifiable variables within lambda expressions in Python 2 – a lambda expression does create a variable scope, like the def statement would, but within lambda no statements are allowed. Assignment being a statement in Python means that no variable assignments in lambda are allowed, but a list comprehension is an expression…

This behaviour has been fixed in Python 3 – no comprehension expressions or generators leak variables.


The global really means the module scope; the main python module is the __main__; all imported modules are accessible through the sys.modules variable; to get access to __main__ one can use sys.modules['__main__'], or import __main__; it is perfectly acceptable to access and assign attributes there; they will show up as variables in the global scope of the main module.


If a name is ever assigned to in the current scope (except in the class scope), it will be considered belonging to that scope, otherwise it will be considered to belonging to any enclosing scope that assigns to the variable (it might not be assigned yet, or not at all), or finally the global scope. If the variable is considered local, but it is not set yet, or has been deleted, reading the variable value will result in UnboundLocalError, which is a subclass of NameError.

x = 5
def foobar():
    print(x)  # causes UnboundLocalError!
    x += 1    # because assignment here makes x a local variable within the function

# call the function
foobar()

The scope can declare that it explicitly wants to modify the global (module scope) variable, with the global keyword:

x = 5
def foobar():
    global x
    print(x)
    x += 1

foobar() # -> 5
print(x) # -> 6

This also is possible even if it was shadowed in enclosing scope:

x = 5
y = 13
def make_closure():
    x = 42
    y = 911
    def func():
        global x # sees the global value
        print(x, y)
        x += 1

    return func

func = make_closure()
func()      # -> 5 911
print(x, y) # -> 6 13

In python 2 there is no easy way to modify the value in the enclosing scope; usually this is simulated by having a mutable value, such as a list with length of 1:

def make_closure():
    value = [0]
    def get_next_value():
        value[0] += 1
        return value[0]

    return get_next_value

get_next = make_closure()
print(get_next()) # -> 1
print(get_next()) # -> 2

However in python 3, the nonlocal comes to rescue:

def make_closure():
    value = 0
    def get_next_value():
        nonlocal value
        value += 1
        return value
    return get_next_value

get_next = make_closure() # identical behavior to the previous example.

The nonlocal documentation says that

Names listed in a nonlocal statement, unlike those listed in a global statement, must refer to pre-existing bindings in an enclosing scope (the scope in which a new binding should be created cannot be determined unambiguously).

i.e. nonlocal always refers to the innermost outer non-global scope where the name has been bound (i.e. assigned to, including used as the for target variable, in the with clause, or as a function parameter).


Any variable that is not deemed to be local to the current scope, or any enclosing scope, is a global variable. A global name is looked up in the module global dictionary; if not found, the global is then looked up from the builtins module; the name of the module was changed from python 2 to python 3; in python 2 it was __builtin__ and in python 3 it is now called builtins. If you assign to an attribute of builtins module, it will be visible thereafter to any module as a readable global variable, unless that module shadows them with its own global variable with the same name.


Reading the builtin module can also be useful; suppose that you want the python 3 style print function in some parts of file, but other parts of file still use the print statement. In Python 2.6-2.7 you can get hold of the Python 3 print function with:

import __builtin__

print3 = __builtin__.__dict__['print']

The from __future__ import print_function actually does not import the print function anywhere in Python 2 – instead it just disables the parsing rules for print statement in the current module, handling print like any other variable identifier, and thus allowing the print the function be looked up in the builtins.


回答 3

其他答案中已经概述了Python 2.x的范围规则。我唯一要补充的是,在Python 3.0中,还有一个非本地范围的概念(由’nonlocal’关键字指示)。这使您可以直接访问外部作用域,并可以进行一些巧妙的技巧,包括词法关闭(没有涉及可变对象的难看的技巧)。

编辑:这是PEP,对此有更多信息。

The scoping rules for Python 2.x have been outlined already in other answers. The only thing I would add is that in Python 3.0, there is also the concept of a non-local scope (indicated by the ‘nonlocal’ keyword). This allows you to access outer scopes directly, and opens up the ability to do some neat tricks, including lexical closures (without ugly hacks involving mutable objects).

EDIT: Here’s the PEP with more information on this.


回答 4

范围的更完整示例:

from __future__ import print_function  # for python 2 support

x = 100
print("1. Global x:", x)
class Test(object):
    y = x
    print("2. Enclosed y:", y)
    x = x + 1
    print("3. Enclosed x:", x)

    def method(self):
        print("4. Enclosed self.x", self.x)
        print("5. Global x", x)
        try:
            print(y)
        except NameError as e:
            print("6.", e)

    def method_local_ref(self):
        try:
            print(x)
        except UnboundLocalError as e:
            print("7.", e)
        x = 200 # causing 7 because has same name
        print("8. Local x", x)

inst = Test()
inst.method()
inst.method_local_ref()

输出:

1. Global x: 100
2. Enclosed y: 100
3. Enclosed x: 101
4. Enclosed self.x 101
5. Global x 100
6. global name 'y' is not defined
7. local variable 'x' referenced before assignment
8. Local x 200

A slightly more complete example of scope:

from __future__ import print_function  # for python 2 support

x = 100
print("1. Global x:", x)
class Test(object):
    y = x
    print("2. Enclosed y:", y)
    x = x + 1
    print("3. Enclosed x:", x)

    def method(self):
        print("4. Enclosed self.x", self.x)
        print("5. Global x", x)
        try:
            print(y)
        except NameError as e:
            print("6.", e)

    def method_local_ref(self):
        try:
            print(x)
        except UnboundLocalError as e:
            print("7.", e)
        x = 200 # causing 7 because has same name
        print("8. Local x", x)

inst = Test()
inst.method()
inst.method_local_ref()

output:

1. Global x: 100
2. Enclosed y: 100
3. Enclosed x: 101
4. Enclosed self.x 101
5. Global x 100
6. global name 'y' is not defined
7. local variable 'x' referenced before assignment
8. Local x 200

回答 5

Python通常使用三个可用的命名空间来解析变量。

在执行过程中的任何时候,至少有三个嵌套作用域可以直接访问其命名空间:最先搜索的最内部作用域包含本地名称;任何封闭函数的命名空间,它们从最近的封闭范围开始搜索;接下来搜索的中间范围包含当前模块的全局名称;最外面的作用域(最后搜索)是包含内置名称的命名空间。

有两个函数:globalslocals,它们向您显示这些命名空间中的两个。

命名空间是由包,模块,类,对象构造和函数创建的。没有其他类型的命名空间。

在这种情况下,x必须在本地命名空间或全局命名空间中解析对名为的函数的调用。

在这种情况下,局部变量是方法函数的主体Foo.spam

全球是-很好-全球。

规则是搜索由方法函数(和嵌套函数定义)创建的嵌套局部空间,然后全局搜索。而已。

没有其他范围。该for语句(以及其他复合语句,如iftry)不会创建新的嵌套作用域。仅定义(包,模块,函数,类和对象实例。)

在类定义中,名称是类命名空间的一部分。 code2,例如,必须由类名限定。一般而言Foo.code2。但是,self.code2由于Python对象会将包含的类视为备用类,因此也可以使用。

对象(类的实例)具有实例变量。这些名称位于对象的命名空间中。它们必须由对象限定。(variable.instance。)

在类方法中,您具有局部变量和全局变量。您说self.variable选择实例作为命名空间。您会注意到,这self是每个类成员函数的参数,使其成为本地命名空间的一部分。

请参见Python作用域规则Python作用域变量作用域

Python resolves your variables with — generally — three namespaces available.

At any time during execution, there are at least three nested scopes whose namespaces are directly accessible: the innermost scope, which is searched first, contains the local names; the namespaces of any enclosing functions, which are searched starting with the nearest enclosing scope; the middle scope, searched next, contains the current module’s global names; and the outermost scope (searched last) is the namespace containing built-in names.

There are two functions: globals and locals which show you the contents two of these namespaces.

Namespaces are created by packages, modules, classes, object construction and functions. There aren’t any other flavors of namespaces.

In this case, the call to a function named x has to be resolved in the local name space or the global namespace.

Local in this case, is the body of the method function Foo.spam.

Global is — well — global.

The rule is to search the nested local spaces created by method functions (and nested function definitions), then search global. That’s it.

There are no other scopes. The for statement (and other compound statements like if and try) don’t create new nested scopes. Only definitions (packages, modules, functions, classes and object instances.)

Inside a class definition, the names are part of the class namespace. code2, for instance, must be qualified by the class name. Generally Foo.code2. However, self.code2 will also work because Python objects look at the containing class as a fall-back.

An object (an instance of a class) has instance variables. These names are in the object’s namespace. They must be qualified by the object. (variable.instance.)

From within a class method, you have locals and globals. You say self.variable to pick the instance as the namespace. You’ll note that self is an argument to every class member function, making it part of the local namespace.

See Python Scope Rules, Python Scope, Variable Scope.


回答 6

在哪里找到x?

找不到x,因为您尚未定义x。:-)如果将其放在代码1(全局)或代码3(本地)中,则可以找到它。

code2(类成员)对于相同类的方法内部的代码不可见-您通常可以使用self来访问它们。code4 / code5(循环)的作用域与code3相同,因此,如果您在其中写入x,则将更改code3中定义的x实例,而不创建新的x。

Python是静态作用域的,因此,如果您将“垃圾邮件”传递给另一个函数,则垃圾邮件仍可访问其来源模块(在code1中定义)以及其他任何包含作用域的模块中的全局变量(请参见下文)。code2成员将再次通过self访问。

lambda和def一样。如果在函数内部使用了lambda,则与定义嵌套函数相同。从Python 2.2开始,可以使用嵌套作用域。在这种情况下,您可以在函数嵌套的任何级别绑定x,Python将选择最里面的实例:

x= 0
def fun1():
    x= 1
    def fun2():
        x= 2
        def fun3():
            return x
        return fun3()
    return fun2()
print fun1(), x

2 0

fun3从最近的包含范围(与fun2关联的函数范围)中看到实例x。但是在fun1和全局中定义的其他x实例不受影响。

在nested_scopes之前(在Python 2.1之前的版本中以及在2.1中,除非您专门使用from-future-import要求功能),fun3不可见fun1和fun2的作用域,因此S.Lott的答案成立,您将获得全局x :

0 0

Where is x found?

x is not found as you haven’t defined it. :-) It could be found in code1 (global) or code3 (local) if you put it there.

code2 (class members) aren’t visible to code inside methods of the same class — you would usually access them using self. code4/code5 (loops) live in the same scope as code3, so if you wrote to x in there you would be changing the x instance defined in code3, not making a new x.

Python is statically scoped, so if you pass ‘spam’ to another function spam will still have access to globals in the module it came from (defined in code1), and any other containing scopes (see below). code2 members would again be accessed through self.

lambda is no different to def. If you have a lambda used inside a function, it’s the same as defining a nested function. In Python 2.2 onwards, nested scopes are available. In this case you can bind x at any level of function nesting and Python will pick up the innermost instance:

x= 0
def fun1():
    x= 1
    def fun2():
        x= 2
        def fun3():
            return x
        return fun3()
    return fun2()
print fun1(), x

2 0

fun3 sees the instance x from the nearest containing scope, which is the function scope associated with fun2. But the other x instances, defined in fun1 and globally, are not affected.

Before nested_scopes — in Python pre-2.1, and in 2.1 unless you specifically ask for the feature using a from-future-import — fun1 and fun2’s scopes are not visible to fun3, so S.Lott’s answer holds and you would get the global x:

0 0

回答 7

在Python中,

分配了值的任何变量对于分配在其中出现的块都是局部的。

如果在当前范围内找不到变量,请参考LEGB顺序。

In Python,

any variable that is assigned a value is local to the block in which the assignment appears.

If a variable can’t be found in the current scope, please refer to the LEGB order.


将utf-8文本保存在json.dumps中为UTF8,而不是\ u转义序列

问题:将utf-8文本保存在json.dumps中为UTF8,而不是\ u转义序列

样例代码:

>>> import json
>>> json_string = json.dumps("ברי צקלה")
>>> print json_string
"\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"

问题:这不是人类可读的。我的(智能)用户想要使用JSON转储来验证甚至编辑文本文件(我宁愿不使用XML)。

有没有一种方法可以将对象序列化为UTF-8 JSON字符串(而不是 \uXXXX)?

sample code:

>>> import json
>>> json_string = json.dumps("ברי צקלה")
>>> print json_string
"\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"

The problem: it’s not human readable. My (smart) users want to verify or even edit text files with JSON dumps (and I’d rather not use XML).

Is there a way to serialize objects into UTF-8 JSON strings (instead of \uXXXX)?


回答 0

使用ensure_ascii=False切换至json.dumps(),然后手动将值编码为UTF-8:

>>> json_string = json.dumps("ברי צקלה", ensure_ascii=False).encode('utf8')
>>> json_string
b'"\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94"'
>>> print(json_string.decode())
"ברי צקלה"

如果要写入文件,只需使用json.dump()并将其留给文件对象进行编码:

with open('filename', 'w', encoding='utf8') as json_file:
    json.dump("ברי צקלה", json_file, ensure_ascii=False)

Python 2警告

对于Python 2,还有更多注意事项需要考虑。如果要将其写入文件,则可以使用io.open()代替open()来生成一个文件对象,该对象在编写时为您编码Unicode值,然后使用json.dump()代替来写入该文件:

with io.open('filename', 'w', encoding='utf8') as json_file:
    json.dump(u"ברי צקלה", json_file, ensure_ascii=False)

做笔记,有一对在错误json模块,其中ensure_ascii=False标志可以产生一个混合unicodestr对象。那么,Python 2的解决方法是:

with io.open('filename', 'w', encoding='utf8') as json_file:
    data = json.dumps(u"ברי צקלה", ensure_ascii=False)
    # unicode(data) auto-decodes data to unicode if str
    json_file.write(unicode(data))

在Python 2中,当使用str编码为UTF-8的字节字符串(类型)时,请确保还设置encoding关键字:

>>> d={ 1: "ברי צקלה", 2: u"ברי צקלה" }
>>> d
{1: '\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94', 2: u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'}

>>> s=json.dumps(d, ensure_ascii=False, encoding='utf8')
>>> s
u'{"1": "\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4", "2": "\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"}'
>>> json.loads(s)['1']
u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'
>>> json.loads(s)['2']
u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'
>>> print json.loads(s)['1']
ברי צקלה
>>> print json.loads(s)['2']
ברי צקלה

Use the ensure_ascii=False switch to json.dumps(), then encode the value to UTF-8 manually:

>>> json_string = json.dumps("ברי צקלה", ensure_ascii=False).encode('utf8')
>>> json_string
b'"\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94"'
>>> print(json_string.decode())
"ברי צקלה"

If you are writing to a file, just use json.dump() and leave it to the file object to encode:

with open('filename', 'w', encoding='utf8') as json_file:
    json.dump("ברי צקלה", json_file, ensure_ascii=False)

Caveats for Python 2

For Python 2, there are some more caveats to take into account. If you are writing this to a file, you can use io.open() instead of open() to produce a file object that encodes Unicode values for you as you write, then use json.dump() instead to write to that file:

with io.open('filename', 'w', encoding='utf8') as json_file:
    json.dump(u"ברי צקלה", json_file, ensure_ascii=False)

Do note that there is a bug in the json module where the ensure_ascii=False flag can produce a mix of unicode and str objects. The workaround for Python 2 then is:

with io.open('filename', 'w', encoding='utf8') as json_file:
    data = json.dumps(u"ברי צקלה", ensure_ascii=False)
    # unicode(data) auto-decodes data to unicode if str
    json_file.write(unicode(data))

In Python 2, when using byte strings (type str), encoded to UTF-8, make sure to also set the encoding keyword:

>>> d={ 1: "ברי צקלה", 2: u"ברי צקלה" }
>>> d
{1: '\xd7\x91\xd7\xa8\xd7\x99 \xd7\xa6\xd7\xa7\xd7\x9c\xd7\x94', 2: u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'}

>>> s=json.dumps(d, ensure_ascii=False, encoding='utf8')
>>> s
u'{"1": "\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4", "2": "\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"}'
>>> json.loads(s)['1']
u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'
>>> json.loads(s)['2']
u'\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4'
>>> print json.loads(s)['1']
ברי צקלה
>>> print json.loads(s)['2']
ברי צקלה

回答 1

写入文件

import codecs
import json

with codecs.open('your_file.txt', 'w', encoding='utf-8') as f:
    json.dump({"message":"xin chào việt nam"}, f, ensure_ascii=False)

打印到标准输出

import json
print(json.dumps({"message":"xin chào việt nam"}, ensure_ascii=False))

To write to a file

import codecs
import json

with codecs.open('your_file.txt', 'w', encoding='utf-8') as f:
    json.dump({"message":"xin chào việt nam"}, f, ensure_ascii=False)

To print to stdout

import json
print(json.dumps({"message":"xin chào việt nam"}, ensure_ascii=False))

回答 2

更新:这是错误的答案,但是了解为什么它仍然是有用的。看评论。

怎么unicode-escape

>>> d = {1: "ברי צקלה", 2: u"ברי צקלה"}
>>> json_str = json.dumps(d).decode('unicode-escape').encode('utf8')
>>> print json_str
{"1": "ברי צקלה", "2": "ברי צקלה"}

UPDATE: This is wrong answer, but it’s still useful to understand why it’s wrong. See comments.

How about unicode-escape?

>>> d = {1: "ברי צקלה", 2: u"ברי צקלה"}
>>> json_str = json.dumps(d).decode('unicode-escape').encode('utf8')
>>> print json_str
{"1": "ברי צקלה", "2": "ברי צקלה"}

回答 3

Peters的python 2解决方法在边缘情况下失败:

d = {u'keyword': u'bad credit  \xe7redit cards'}
with io.open('filename', 'w', encoding='utf8') as json_file:
    data = json.dumps(d, ensure_ascii=False).decode('utf8')
    try:
        json_file.write(data)
    except TypeError:
        # Decode data to Unicode first
        json_file.write(data.decode('utf8'))

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe7' in position 25: ordinal not in range(128)

它在第3行的.decode(’utf8’)部分崩溃。我通过避免该步骤以及ascii的特殊大小写,使程序更加简单,从而解决了该问题:

with io.open('filename', 'w', encoding='utf8') as json_file:
  data = json.dumps(d, ensure_ascii=False, encoding='utf8')
  json_file.write(unicode(data))

cat filename
{"keyword": "bad credit  çredit cards"}

Peters’ python 2 workaround fails on an edge case:

d = {u'keyword': u'bad credit  \xe7redit cards'}
with io.open('filename', 'w', encoding='utf8') as json_file:
    data = json.dumps(d, ensure_ascii=False).decode('utf8')
    try:
        json_file.write(data)
    except TypeError:
        # Decode data to Unicode first
        json_file.write(data.decode('utf8'))

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe7' in position 25: ordinal not in range(128)

It was crashing on the .decode(‘utf8’) part of line 3. I fixed the problem by making the program much simpler by avoiding that step as well as the special casing of ascii:

with io.open('filename', 'w', encoding='utf8') as json_file:
  data = json.dumps(d, ensure_ascii=False, encoding='utf8')
  json_file.write(unicode(data))

cat filename
{"keyword": "bad credit  çredit cards"}

回答 4

从Python 3.7开始,以下代码可以正常运行:

from json import dumps
result = {"symbol": "ƒ"}
json_string = dumps(result, sort_keys=True, indent=2, ensure_ascii=False)
print(json_string)

输出:

{"symbol": "ƒ"}

As of Python 3.7 the following code works fine:

from json import dumps
result = {"symbol": "ƒ"}
json_string = dumps(result, sort_keys=True, indent=2, ensure_ascii=False)
print(json_string)

Output:

{"symbol": "ƒ"}

回答 5

以下是我和google的var阅读答案。

# coding:utf-8
r"""
@update: 2017-01-09 14:44:39
@explain: str, unicode, bytes in python2to3
    #python2 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 7: ordinal not in range(128)
    #1.reload
    #importlib,sys
    #importlib.reload(sys)
    #sys.setdefaultencoding('utf-8') #python3 don't have this attribute.
    #not suggest even in python2 #see:http://stackoverflow.com/questions/3828723/why-should-we-not-use-sys-setdefaultencodingutf-8-in-a-py-script
    #2.overwrite /usr/lib/python2.7/sitecustomize.py or (sitecustomize.py and PYTHONPATH=".:$PYTHONPATH" python)
    #too complex
    #3.control by your own (best)
    #==> all string must be unicode like python3 (u'xx'|b'xx'.encode('utf-8')) (unicode 's disappeared in python3)
    #see: http://blog.ernest.me/post/python-setdefaultencoding-unicode-bytes

    #how to Saving utf-8 texts in json.dumps as UTF8, not as \u escape sequence
    #http://stackoverflow.com/questions/18337407/saving-utf-8-texts-in-json-dumps-as-utf8-not-as-u-escape-sequence
"""

from __future__ import print_function
import json

a = {"b": u"中文"}  # add u for python2 compatibility
print('%r' % a)
print('%r' % json.dumps(a))
print('%r' % (json.dumps(a).encode('utf8')))
a = {"b": u"中文"}
print('%r' % json.dumps(a, ensure_ascii=False))
print('%r' % (json.dumps(a, ensure_ascii=False).encode('utf8')))
# print(a.encode('utf8')) #AttributeError: 'dict' object has no attribute 'encode'
print('')

# python2:bytes=str; python3:bytes
b = a['b'].encode('utf-8')
print('%r' % b)
print('%r' % b.decode("utf-8"))
print('')

# python2:unicode; python3:str=unicode
c = b.decode('utf-8')
print('%r' % c)
print('%r' % c.encode('utf-8'))
"""
#python2
{'b': u'\u4e2d\u6587'}
'{"b": "\\u4e2d\\u6587"}'
'{"b": "\\u4e2d\\u6587"}'
u'{"b": "\u4e2d\u6587"}'
'{"b": "\xe4\xb8\xad\xe6\x96\x87"}'

'\xe4\xb8\xad\xe6\x96\x87'
u'\u4e2d\u6587'

u'\u4e2d\u6587'
'\xe4\xb8\xad\xe6\x96\x87'

#python3
{'b': '中文'}
'{"b": "\\u4e2d\\u6587"}'
b'{"b": "\\u4e2d\\u6587"}'
'{"b": "中文"}'
b'{"b": "\xe4\xb8\xad\xe6\x96\x87"}'

b'\xe4\xb8\xad\xe6\x96\x87'
'中文'

'中文'
b'\xe4\xb8\xad\xe6\x96\x87'
"""

The following is my understanding var reading answer above and google.

# coding:utf-8
r"""
@update: 2017-01-09 14:44:39
@explain: str, unicode, bytes in python2to3
    #python2 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 7: ordinal not in range(128)
    #1.reload
    #importlib,sys
    #importlib.reload(sys)
    #sys.setdefaultencoding('utf-8') #python3 don't have this attribute.
    #not suggest even in python2 #see:http://stackoverflow.com/questions/3828723/why-should-we-not-use-sys-setdefaultencodingutf-8-in-a-py-script
    #2.overwrite /usr/lib/python2.7/sitecustomize.py or (sitecustomize.py and PYTHONPATH=".:$PYTHONPATH" python)
    #too complex
    #3.control by your own (best)
    #==> all string must be unicode like python3 (u'xx'|b'xx'.encode('utf-8')) (unicode 's disappeared in python3)
    #see: http://blog.ernest.me/post/python-setdefaultencoding-unicode-bytes

    #how to Saving utf-8 texts in json.dumps as UTF8, not as \u escape sequence
    #http://stackoverflow.com/questions/18337407/saving-utf-8-texts-in-json-dumps-as-utf8-not-as-u-escape-sequence
"""

from __future__ import print_function
import json

a = {"b": u"中文"}  # add u for python2 compatibility
print('%r' % a)
print('%r' % json.dumps(a))
print('%r' % (json.dumps(a).encode('utf8')))
a = {"b": u"中文"}
print('%r' % json.dumps(a, ensure_ascii=False))
print('%r' % (json.dumps(a, ensure_ascii=False).encode('utf8')))
# print(a.encode('utf8')) #AttributeError: 'dict' object has no attribute 'encode'
print('')

# python2:bytes=str; python3:bytes
b = a['b'].encode('utf-8')
print('%r' % b)
print('%r' % b.decode("utf-8"))
print('')

# python2:unicode; python3:str=unicode
c = b.decode('utf-8')
print('%r' % c)
print('%r' % c.encode('utf-8'))
"""
#python2
{'b': u'\u4e2d\u6587'}
'{"b": "\\u4e2d\\u6587"}'
'{"b": "\\u4e2d\\u6587"}'
u'{"b": "\u4e2d\u6587"}'
'{"b": "\xe4\xb8\xad\xe6\x96\x87"}'

'\xe4\xb8\xad\xe6\x96\x87'
u'\u4e2d\u6587'

u'\u4e2d\u6587'
'\xe4\xb8\xad\xe6\x96\x87'

#python3
{'b': '中文'}
'{"b": "\\u4e2d\\u6587"}'
b'{"b": "\\u4e2d\\u6587"}'
'{"b": "中文"}'
b'{"b": "\xe4\xb8\xad\xe6\x96\x87"}'

b'\xe4\xb8\xad\xe6\x96\x87'
'中文'

'中文'
b'\xe4\xb8\xad\xe6\x96\x87'
"""

回答 6

这是我使用json.dump()的解决方案:

def jsonWrite(p, pyobj, ensure_ascii=False, encoding=SYSTEM_ENCODING, **kwargs):
    with codecs.open(p, 'wb', 'utf_8') as fileobj:
        json.dump(pyobj, fileobj, ensure_ascii=ensure_ascii,encoding=encoding, **kwargs)

其中SYSTEM_ENCODING设置为:

locale.setlocale(locale.LC_ALL, '')
SYSTEM_ENCODING = locale.getlocale()[1]

Here’s my solution using json.dump():

def jsonWrite(p, pyobj, ensure_ascii=False, encoding=SYSTEM_ENCODING, **kwargs):
    with codecs.open(p, 'wb', 'utf_8') as fileobj:
        json.dump(pyobj, fileobj, ensure_ascii=ensure_ascii,encoding=encoding, **kwargs)

where SYSTEM_ENCODING is set to:

locale.setlocale(locale.LC_ALL, '')
SYSTEM_ENCODING = locale.getlocale()[1]

回答 7

尽可能使用编解码器,

with codecs.open('file_path', 'a+', 'utf-8') as fp:
    fp.write(json.dumps(res, ensure_ascii=False))

Use codecs if possible,

with codecs.open('file_path', 'a+', 'utf-8') as fp:
    fp.write(json.dumps(res, ensure_ascii=False))

回答 8

感谢您在这里的原始答案。使用python 3的以下代码行:

print(json.dumps(result_dict,ensure_ascii=False))

还可以 如果不是必须的,请考虑尝试在代码中不要写太多文本。

这对于python控制台可能已经足够了。但是,要使服务器满意,您可能需要按照此处的说明设置语言环境(如果它在apache2上) http://blog.dscpl.com.au/2014/09/setting-lang-and-lcall-when-using .html

基本上在ubuntu上安装he_IL或​​任何语言环境,检查是否未安装

locale -a 

将其安装在XX是您的语言的位置

sudo apt-get install language-pack-XX

例如:

sudo apt-get install language-pack-he

将以下文本添加到/ etc / apache2 / envvrs

export LANG='he_IL.UTF-8'
export LC_ALL='he_IL.UTF-8'

比您希望不要从apache上得到python错误:

打印(js)UnicodeEncodeError:’ascii’编解码器无法在位置41-45处编码字符:序数不在范围内(128)

另外,在apache中,尝试将utf设置为默认编码,如下所示:
如何将Apache的默认编码更改为UTF-8?

尽早执行,因为apache错误可能很难调试,并且您可能会错误地认为它来自python,在这种情况下可能并非如此

Thanks for the original answer here. With python 3 the following line of code:

print(json.dumps(result_dict,ensure_ascii=False))

was ok. Consider trying not writing too much text in the code if it’s not imperative.

This might be good enough for the python console. However, to satisfy a server you might need to set the locale as explained here (if it is on apache2) http://blog.dscpl.com.au/2014/09/setting-lang-and-lcall-when-using.html

basically install he_IL or whatever language locale on ubuntu check it is not installed

locale -a 

install it where XX is your language

sudo apt-get install language-pack-XX

For example:

sudo apt-get install language-pack-he

add the following text to /etc/apache2/envvrs

export LANG='he_IL.UTF-8'
export LC_ALL='he_IL.UTF-8'

Than you would hopefully not get python errors on from apache like:

print (js) UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position 41-45: ordinal not in range(128)

Also in apache try to make utf the default encoding as explained here:
How to change the default encoding to UTF-8 for Apache?

Do it early because apache errors can be pain to debug and you can mistakenly think it’s from python which possibly isn’t the case in that situation


回答 9

如果要从文件和文件内容阿拉伯文本加载JSON字符串。然后这将起作用。

假设文件如下:arabic.json

{ 
"key1" : "لمستخدمين",
"key2" : "إضافة مستخدم"
}

从arabic.json文件获取阿拉伯语内容

with open(arabic.json, encoding='utf-8') as f:
   # deserialises it
   json_data = json.load(f)
   f.close()


# json formatted string
json_data2 = json.dumps(json_data, ensure_ascii = False)

要在Django模板中使用JSON数据,请执行以下步骤:

# If have to get the JSON index in Django Template file, then simply decode the encoded string.

json.JSONDecoder().decode(json_data2)

完成了!现在我们可以将结果作为带有阿拉伯值的JSON索引来获取。

If you are loading JSON string from a file & file contents arabic texts. Then this will work.

Assume File like: arabic.json

{ 
"key1" : "لمستخدمين",
"key2" : "إضافة مستخدم"
}

Get the arabic contents from the arabic.json file

with open(arabic.json, encoding='utf-8') as f:
   # deserialises it
   json_data = json.load(f)
   f.close()


# json formatted string
json_data2 = json.dumps(json_data, ensure_ascii = False)

To use JSON Data in Django Template follow below steps:

# If have to get the JSON index in Django Template file, then simply decode the encoded string.

json.JSONDecoder().decode(json_data2)

done! Now we can get the results as JSON index with arabic value.


回答 10

使用unicode-escape解决问题

>>>import json
>>>json_string = json.dumps("ברי צקלה")
>>>json_string.encode('ascii').decode('unicode-escape')
'"ברי צקלה"'

说明

>>>s = '漢  χαν  хан'
>>>print('unicode: ' + s.encode('unicode-escape').decode('utf-8'))
unicode: \u6f22  \u03c7\u03b1\u03bd  \u0445\u0430\u043d

>>>u = s.encode('unicode-escape').decode('utf-8')
>>>print('original: ' + u.encode("utf-8").decode('unicode-escape'))
original:   χαν  хан

原始资源:https : //blog.csdn.net/chuatony/article/details/72628868

use unicode-escape to solve problem

>>>import json
>>>json_string = json.dumps("ברי צקלה")
>>>json_string.encode('ascii').decode('unicode-escape')
'"ברי צקלה"'

explain

>>>s = '漢  χαν  хан'
>>>print('unicode: ' + s.encode('unicode-escape').decode('utf-8'))
unicode: \u6f22  \u03c7\u03b1\u03bd  \u0445\u0430\u043d

>>>u = s.encode('unicode-escape').decode('utf-8')
>>>print('original: ' + u.encode("utf-8").decode('unicode-escape'))
original: 漢  χαν  хан

original resource:https://blog.csdn.net/chuatony/article/details/72628868


回答 11

正如Martijn指出的那样,在json.dumps中使用suresure_ascii = False是解决此问题的正确方向。但是,这可能会引发异常:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 1: ordinal not in range(128)

您需要在site.py或sitecustomize.py中进行其他设置,才能正确设置sys.getdefaultencoding()。site.py在lib / python2.7 /下,sitecustomize.py在lib / python2.7 / site-packages下。

如果要使用site.py,请在def setencoding()下:将第一个if 0:更改为if 1 :,以便python使用操作系统的语言环境。

如果您喜欢使用sitecustomize.py,那么如果尚未创建,则可能不存在。只需将这些行:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

然后,您可以以utf-8格式进行中文json输出,例如:

name = {"last_name": u"王"}
json.dumps(name, ensure_ascii=False)

您将获得一个utf-8编码的字符串,而不是\ u转义的json字符串。

验证默认编码:

print sys.getdefaultencoding()

您应该获得“ utf-8”或“ UTF-8”来验证site.py或sitecustomize.py设置。

请注意,您无法在交互式python控制台上执行sys.setdefaultencoding(“ utf-8”)。

Using ensure_ascii=False in json.dumps is the right direction to solve this problem, as pointed out by Martijn. However, this may raise an exception:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 1: ordinal not in range(128)

You need extra settings in either site.py or sitecustomize.py to set your sys.getdefaultencoding() correct. site.py is under lib/python2.7/ and sitecustomize.py is under lib/python2.7/site-packages.

If you want to use site.py, under def setencoding(): change the first if 0: to if 1: so that python will use your operation system’s locale.

If you prefer to use sitecustomize.py, which may not exist if you haven’t created it. simply put these lines:

import sys
reload(sys)
sys.setdefaultencoding('utf-8')

Then you can do some Chinese json output in utf-8 format, such as:

name = {"last_name": u"王"}
json.dumps(name, ensure_ascii=False)

You will get an utf-8 encoded string, rather than \u escaped json string.

To verify your default encoding:

print sys.getdefaultencoding()

You should get “utf-8” or “UTF-8” to verify your site.py or sitecustomize.py settings.

Please note that you could not do sys.setdefaultencoding(“utf-8”) at interactive python console.


在Matplotlib中,该参数在fig.add_subplot(111)中意味着什么?

问题:在Matplotlib中,该参数在fig.add_subplot(111)中意味着什么?

有时我遇到这样的代码:

import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]
fig = plt.figure()
fig.add_subplot(111)
plt.scatter(x, y)
plt.show()

生成:

包含的代码生成的示例图

我一直在疯狂地阅读文档,但找不到关于的解释111。有时我看到一个212

论据fig.add_subplot()是什么意思?

Sometimes I come across code such as this:

import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [1, 4, 9, 16, 25]
fig = plt.figure()
fig.add_subplot(111)
plt.scatter(x, y)
plt.show()

Which produces:

Example plot produced by the included code

I’ve been reading the documentation like crazy but I can’t find an explanation for the 111. sometimes I see a 212.

What does the argument of fig.add_subplot() mean?


回答 0

这些是编码为单个整数的子图网格参数。例如,“ 111”表示“ 1×1网格,第一个子图”,而“ 234”表示“ 2×3网格,第4个子图”。

的替代形式add_subplot(111)add_subplot(1, 1, 1)

These are subplot grid parameters encoded as a single integer. For example, “111” means “1×1 grid, first subplot” and “234” means “2×3 grid, 4th subplot”.

Alternative form for add_subplot(111) is add_subplot(1, 1, 1).


回答 1

我认为最好用以下图片解释:

在此处输入图片说明

要初始化以上内容,请输入:

import matplotlib.pyplot as plt
fig = plt.figure()
fig.add_subplot(221)   #top left
fig.add_subplot(222)   #top right
fig.add_subplot(223)   #bottom left
fig.add_subplot(224)   #bottom right 
plt.show()

I think this would be best explained by the following picture:

enter image description here

To initialize the above, one would type:

import matplotlib.pyplot as plt
fig = plt.figure()
fig.add_subplot(221)   #top left
fig.add_subplot(222)   #top right
fig.add_subplot(223)   #bottom left
fig.add_subplot(224)   #bottom right 
plt.show()

回答 2

康斯坦丁的答案很明确,但对于更多背景,此行为是从Matlab继承的。

Matlab文档的“ 图形设置-每个图形显示多个图形”部分介绍了Matlab行为。

subplot(m,n,i)将图形窗口分成小子图的m×n矩阵,并为当前图选择ithe子图。地标沿着图形窗口的第一行编号,然后是第二行,依此类推。

The answer from Constantin is spot on but for more background this behavior is inherited from Matlab.

The Matlab behavior is explained in the Figure Setup – Displaying Multiple Plots per Figure section of the Matlab documentation.

subplot(m,n,i) breaks the figure window into an m-by-n matrix of small subplots and selects the ithe subplot for the current plot. The plots are numbered along the top row of the figure window, then the second row, and so forth.


回答 3

我的解决方案是

fig = plt.figure()
fig.add_subplot(1, 2, 1)   #top and bottom left
fig.add_subplot(2, 2, 2)   #top right
fig.add_subplot(2, 2, 4)   #bottom right 
plt.show()

具有1和3合并的2x2网格

My solution is

fig = plt.figure()
fig.add_subplot(1, 2, 1)   #top and bottom left
fig.add_subplot(2, 2, 2)   #top right
fig.add_subplot(2, 2, 4)   #bottom right 
plt.show()

2x2 grid with 1 and 3 merge


回答 4

在此处输入图片说明

import matplotlib.pyplot as plt
plt.figure(figsize=(8,8))
plt.subplot(3,2,1)
plt.subplot(3,2,3)
plt.subplot(3,2,5)
plt.subplot(2,2,2)
plt.subplot(2,2,4)

第一个代码在具有3行2列的布局中创建第一个子图。

第一列中的三个图形表示3行。第二个图位于同一列中的第一个图的正下方,依此类推。

最后两个图的参数(2, 2)表示第二列只有两行,位置参数逐行移动。

enter image description here

import matplotlib.pyplot as plt
plt.figure(figsize=(8,8))
plt.subplot(3,2,1)
plt.subplot(3,2,3)
plt.subplot(3,2,5)
plt.subplot(2,2,2)
plt.subplot(2,2,4)

The first code creates the first subplot in a layout that has 3 rows and 2 columns.

The three graphs in the first column denote the 3 rows. The second plot comes just below the first plot in the same column and so on.

The last two plots have arguments (2, 2) denoting that the second column has only two rows, the position parameters move row wise.


回答 5

fig.add_subplot(ROW,COLUMN,POSITION)

  • ROW =行数
  • COLUMN =列数
  • POSITION =您要绘制的图形的位置

例子

`fig.add_subplot(111)` #There is only one subplot or graph  
`fig.add_subplot(211)`  *and*  `fig.add_subplot(212)` 

总共有2行1列,因此可以绘制2个子图。它的位置是第一。一共有2行,一列,因此可以绘制2个子图。其位置为第2个

fig.add_subplot(ROW,COLUMN,POSITION)

  • ROW=number of rows
  • COLUMN=number of columns
  • POSITION= position of the graph you are plotting

Examples

`fig.add_subplot(111)` #There is only one subplot or graph  
`fig.add_subplot(211)`  *and*  `fig.add_subplot(212)` 

There are total 2 rows,1 column therefore 2 subgraphs can be plotted. Its location is 1st. There are total 2 rows,1 column therefore 2 subgraphs can be plotted.Its location is 2nd


回答 6

add_subplot()方法有几个调用签名:

  1. add_subplot(nrows, ncols, index, **kwargs)
  2. add_subplot(pos, **kwargs)
  3. add_subplot(ax)
  4. add_subplot() <-自3.1.0起

通话1和2:

呼叫1和2实现彼此相同的功能(最大限制,如下所述)。可以将它们视为首先指定前两个数字(2×2、1×8、3×4等)的网格布局,例如:

f.add_subplot(3,4,1) 
# is equivalent to:
f.add_subplot(341)

两者都产生3行4列的(3 x 4 = 12)子图的子图排列。每次调用中的第三个数字表示要返回的轴对象,从左上方的1开始,向右增加

此代码说明了使用调用2的局限性:

#!/usr/bin/env python3
import matplotlib.pyplot as plt

def plot_and_text(axis, text):
  '''Simple function to add a straight line
  and text to an axis object'''
  axis.plot([0,1],[0,1])
  axis.text(0.02, 0.9, text)

f = plt.figure()
f2 = plt.figure()

_max = 12
for i in range(_max):
  axis = f.add_subplot(3,4,i+1, fc=(0,0,0,i/(_max*2)), xticks=[], yticks=[])
  plot_and_text(axis,chr(i+97) + ') ' + '3,4,' +str(i+1))

  # If this check isn't in place, a 
  # ValueError: num must be 1 <= num <= 15, not 0 is raised
  if i < 9:
    axis = f2.add_subplot(341+i, fc=(0,0,0,i/(_max*2)), xticks=[], yticks=[])
    plot_and_text(axis,chr(i+97) + ') ' + str(341+i))

f.tight_layout()
f2.tight_layout()
plt.show()

子图

您可以看到在LHS上调用1可以返回任何轴对象,但是在RHS上调用2只能返回到index = 9渲染子图j),k)和l)无法访问的状态。

即,它从文档中说明了这一点

pos是一个三位数的整数,其中第一位数是行数,第二位数是列数,第三位数是子图的索引。即fig.add_subplot(235)与fig.add_subplot(2、3、5)相同。请注意,所有整数必须小于10才能起作用


调用3

在极少数情况下,可以使用单个参数调用add_subplot,该子图坐标轴实例已在当前图形中创建,但未在图形的坐标轴列表中创建。


调用4(自3.1.0起):

如果未传递任何位置参数,则默认为(1,1,1)。

即,重现fig.add_subplot(111)问题中的呼叫。

The add_subplot() method has several call signatures:

  1. add_subplot(nrows, ncols, index, **kwargs)
  2. add_subplot(pos, **kwargs)
  3. add_subplot(ax)
  4. add_subplot() <– since 3.1.0

Calls 1 and 2:

Calls 1 and 2 achieve the same thing as one another (up to a limit, explained below). Think of them as first specifying the grid layout with their first 2 numbers (2×2, 1×8, 3×4, etc), e.g:

f.add_subplot(3,4,1) 
# is equivalent to:
f.add_subplot(341)

Both produce a subplot arrangement of (3 x 4 = 12) subplots in 3 rows and 4 columns. The third number in each call indicates which axis object to return, starting from 1 at the top left, increasing to the right.

This code illustrates the limitations of using call 2:

#!/usr/bin/env python3
import matplotlib.pyplot as plt

def plot_and_text(axis, text):
  '''Simple function to add a straight line
  and text to an axis object'''
  axis.plot([0,1],[0,1])
  axis.text(0.02, 0.9, text)

f = plt.figure()
f2 = plt.figure()

_max = 12
for i in range(_max):
  axis = f.add_subplot(3,4,i+1, fc=(0,0,0,i/(_max*2)), xticks=[], yticks=[])
  plot_and_text(axis,chr(i+97) + ') ' + '3,4,' +str(i+1))

  # If this check isn't in place, a 
  # ValueError: num must be 1 <= num <= 15, not 0 is raised
  if i < 9:
    axis = f2.add_subplot(341+i, fc=(0,0,0,i/(_max*2)), xticks=[], yticks=[])
    plot_and_text(axis,chr(i+97) + ') ' + str(341+i))

f.tight_layout()
f2.tight_layout()
plt.show()

subplots

You can see with call 1 on the LHS you can return any axis object, however with call 2 on the RHS you can only return up to index = 9 rendering subplots j), k), and l) inaccessible using this call.

I.e it illustrates this point from the documentation:

pos is a three digit integer, where the first digit is the number of rows, the second the number of columns, and the third the index of the subplot. i.e. fig.add_subplot(235) is the same as fig.add_subplot(2, 3, 5). Note that all integers must be less than 10 for this form to work.


Call 3

In rare circumstances, add_subplot may be called with a single argument, a subplot axes instance already created in the present figure but not in the figure’s list of axes.


Call 4 (since 3.1.0):

If no positional arguments are passed, defaults to (1, 1, 1).

i.e., reproducing the call fig.add_subplot(111) in the question.


在输出中打印Python版本

问题:在输出中打印Python版本

如何从脚本中打印当前Python安装的版本号?

How can I print the version number of the current Python installation from my script?


回答 0

尝试

import sys
print(sys.version)

这将打印完整的版本信息字符串。如果您只想要python版本号,那么BastienLéonard的解决方案是最好的。您可能要检查完整的字符串,看看是否需要它或其中的一部分。

Try

import sys
print(sys.version)

This prints the full version information string. If you only want the python version number, then Bastien Léonard’s solution is the best. You might want to examine the full string and see if you need it or portions of it.


回答 1

import platform
print(platform.python_version())

这打印像

3.7.2

import platform
print(platform.python_version())

This prints something like

3.7.2


回答 2

尝试

python --version 

要么

python -V

这将在终端中返回当前的python版本。

Try

python --version 

or

python -V

This will return a current python version in terminal.


回答 3

import sys  

扩展版

sys.version_info  
sys.version_info(major=3, minor=2, micro=2, releaselevel='final', serial=0)

具体

maj_ver = sys.version_info.major  
repr(maj_ver) 
'3'  

要么

print(sys.version_info.major)
'3'

要么

version = ".".join(map(str, sys.version_info[:3]))
print(version)
'3.2.2'
import sys  

expanded version

sys.version_info  
sys.version_info(major=3, minor=2, micro=2, releaselevel='final', serial=0)

specific

maj_ver = sys.version_info.major  
repr(maj_ver) 
'3'  

or

print(sys.version_info.major)
'3'

or

version = ".".join(map(str, sys.version_info[:3]))
print(version)
'3.2.2'

回答 4

如果您正在使用jupyter笔记本,请尝试:

!python --version

如果使用终端,请尝试:

 python --version

If you are using jupyter notebook Try:

!python --version

If you are using terminal Try:

 python --version

如何将秒转换为小时,分钟和秒?

问题:如何将秒转换为小时,分钟和秒?

我有一个以秒为单位返回信息的函数,但是我需要以小时:分钟:秒存储该信息。

有没有简单的方法可以在Python中将秒转换为这种格式?

I have a function that returns information in seconds, but I need to store that information in hours:minutes:seconds.

Is there an easy way to convert the seconds to this format in Python?


回答 0

您可以使用datetime.timedelta功能:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'

You can use datetime.timedelta function:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'

回答 1

通过使用divmod()仅执行一个除法运算就可以得到商和余数的函数,您只需执行两个数学运算就可以很快得出结果:

m, s = divmod(seconds, 60)
h, m = divmod(m, 60)

然后使用字符串格式将结果转换为所需的输出:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+

By using the divmod() function, which does only a single division to produce both the quotient and the remainder, you can have the result very quickly with only two mathematical operations:

m, s = divmod(seconds, 60)
h, m = divmod(m, 60)

And then use string formatting to convert the result into your desired output:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+

回答 2

我很难说出这种简单的方法(至少我不记得语法),但是可以使用time.strftime,它提供了对格式的更多控制:

from time import strftime
from time import gmtime

strftime("%H:%M:%S", gmtime(666))
'00:11:06'

strftime("%H:%M:%S", gmtime(60*60*24))
'00:00:00'

gmtime用于将秒转换为所需的特殊元组格式strftime()

注意:在23:59:59之后截断

I can hardly name that an easy way (at least I can’t remember the syntax), but it is possible to use time.strftime, which gives more control over formatting:

from time import strftime
from time import gmtime

strftime("%H:%M:%S", gmtime(666))
'00:11:06'

strftime("%H:%M:%S", gmtime(60*60*24))
'00:00:00'

gmtime is used to convert seconds to special tuple format that strftime() requires.

Note: Truncates after 23:59:59


回答 3

使用datetime

使用':0>8'格式:

from datetime import timedelta

"{:0>8}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{:0>8}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{:0>8}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

没有':0>8'格式:

"{}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

使用time

from time import gmtime
from time import strftime

# NOTE: The following resets if it goes over 23:59:59!

strftime("%H:%M:%S", gmtime(125))
# Result: '00:02:05'

strftime("%H:%M:%S", gmtime(60*60*24-1))
# Result: '23:59:59'

strftime("%H:%M:%S", gmtime(60*60*24))
# Result: '00:00:00'

strftime("%H:%M:%S", gmtime(666777))
# Result: '17:12:57'
# Wrong

Using datetime:

With the ':0>8' format:

from datetime import timedelta

"{:0>8}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{:0>8}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{:0>8}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

Without the ':0>8' format:

"{}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

Using time:

from time import gmtime
from time import strftime

# NOTE: The following resets if it goes over 23:59:59!

strftime("%H:%M:%S", gmtime(125))
# Result: '00:02:05'

strftime("%H:%M:%S", gmtime(60*60*24-1))
# Result: '23:59:59'

strftime("%H:%M:%S", gmtime(60*60*24))
# Result: '00:00:00'

strftime("%H:%M:%S", gmtime(666777))
# Result: '17:12:57'
# Wrong

回答 4

这是我的快速技巧:

from humanfriendly import format_timespan
secondsPassed = 1302
format_timespan(secondsPassed)
# '21 minutes and 42 seconds'

有关更多信息,请访问:https : //humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan

This is my quick trick:

from humanfriendly import format_timespan
secondsPassed = 1302
format_timespan(secondsPassed)
# '21 minutes and 42 seconds'

For more info Visit: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan


回答 5

如果您需要获取datetime.time价值,可以使用以下技巧:

my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()

您不能添加timedeltatime,但可以将其添加到datetime

UPD:同一技术的另一种变化:

my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()

而不是1可以使用大于0的任何数字。在这里,我们使用这样的事实,即datetime.fromordinal始终返回组件为零的datetime对象time

If you need to get datetime.time value, you can use this trick:

my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()

You cannot add timedelta to time, but can add it to datetime.

UPD: Yet another variation of the same technique:

my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()

Instead of 1 you can use any number greater than 0. Here we use the fact that datetime.fromordinal will always return datetime object with time component being zero.


回答 6

这就是我的方法。

def sec2time(sec, n_msec=3):
    ''' Convert seconds to 'D days, HH:MM:SS.FFF' '''
    if hasattr(sec,'__len__'):
        return [sec2time(s) for s in sec]
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    d, h = divmod(h, 24)
    if n_msec > 0:
        pattern = '%%02d:%%02d:%%0%d.%df' % (n_msec+3, n_msec)
    else:
        pattern = r'%02d:%02d:%02d'
    if d == 0:
        return pattern % (h, m, s)
    return ('%d days, ' + pattern) % (d, h, m, s)

一些例子:

$ sec2time(10, 3)
Out: '00:00:10.000'

$ sec2time(1234567.8910, 0)
Out: '14 days, 06:56:07'

$ sec2time(1234567.8910, 4)
Out: '14 days, 06:56:07.8910'

$ sec2time([12, 345678.9], 3)
Out: ['00:00:12.000', '4 days, 00:01:18.900']

This is how I got it.

def sec2time(sec, n_msec=3):
    ''' Convert seconds to 'D days, HH:MM:SS.FFF' '''
    if hasattr(sec,'__len__'):
        return [sec2time(s) for s in sec]
    m, s = divmod(sec, 60)
    h, m = divmod(m, 60)
    d, h = divmod(h, 24)
    if n_msec > 0:
        pattern = '%%02d:%%02d:%%0%d.%df' % (n_msec+3, n_msec)
    else:
        pattern = r'%02d:%02d:%02d'
    if d == 0:
        return pattern % (h, m, s)
    return ('%d days, ' + pattern) % (d, h, m, s)

Some examples:

$ sec2time(10, 3)
Out: '00:00:10.000'

$ sec2time(1234567.8910, 0)
Out: '14 days, 06:56:07'

$ sec2time(1234567.8910, 4)
Out: '14 days, 06:56:07.8910'

$ sec2time([12, 345678.9], 3)
Out: ['00:00:12.000', '4 days, 00:01:18.900']

回答 7

以下设置对我有用。

def sec_to_hours(seconds):
    a=str(seconds//3600)
    b=str((seconds%3600)//60)
    c=str((seconds%3600)%60)
    d=["{} hours {} mins {} seconds".format(a, b, c)]
    return d


print(sec_to_hours(10000))
# ['2 hours 46 mins 40 seconds']

print(sec_to_hours(60*60*24+105))
# ['24 hours 1 mins 45 seconds']

The following set worked for me.

def sec_to_hours(seconds):
    a=str(seconds//3600)
    b=str((seconds%3600)//60)
    c=str((seconds%3600)%60)
    d=["{} hours {} mins {} seconds".format(a, b, c)]
    return d


print(sec_to_hours(10000))
# ['2 hours 46 mins 40 seconds']

print(sec_to_hours(60*60*24+105))
# ['24 hours 1 mins 45 seconds']

回答 8

dateutil.relativedelta如果您还需要访问浮点数的小时,分​​钟和秒,则非常方便。datetime.timedelta没有提供类似的界面。

from dateutil.relativedelta import relativedelta
rt = relativedelta(seconds=5440)
print(rt.seconds)
print('{:02d}:{:02d}:{:02d}'.format(
    int(rt.hours), int(rt.minutes), int(rt.seconds)))

版画

40.0
01:30:40

dateutil.relativedelta is convenient if you need to access hours, minutes and seconds as floats as well. datetime.timedelta does not provide a similar interface.

from dateutil.relativedelta import relativedelta
rt = relativedelta(seconds=5440)
print(rt.seconds)
print('{:02d}:{:02d}:{:02d}'.format(
    int(rt.hours), int(rt.minutes), int(rt.seconds)))

Prints

40.0
01:30:40

回答 9

小时(h)由楼层的秒数(//)除以3600(60分钟/小时* 60秒/分钟)

分钟(m),以剩余秒数(小时计算的剩余百分比,%)除以60(60秒/分钟)计算得出

类似地,以小时和分钟的余数计算秒数。

其余只是字符串格式!

def hms(seconds):
    h = seconds // 3600
    m = seconds % 3600 // 60
    s = seconds % 3600 % 60
    return '{:02d}:{:02d}:{:02d}'.format(h, m, s)

print(hms(7500))  # Should print 02h05m00s

hours (h) calculated by floor division (by //) of seconds by 3600 (60 min/hr * 60 sec/min)

minutes (m) calculated by floor division of remaining seconds (remainder from hour calculation, by %) by 60 (60 sec/min)

similarly, seconds (s) by remainder of hour and minutes calculation.

Rest is just string formatting!

def hms(seconds):
    h = seconds // 3600
    m = seconds % 3600 // 60
    s = seconds % 3600 % 60
    return '{:02d}:{:02d}:{:02d}'.format(h, m, s)

print(hms(7500))  # Should print 02h05m00s

回答 10

您可以将秒除以60得到分钟

import time
seconds = time.time()
minutes = seconds / 60
print(minutes)

再次将其除以60,就可以得到小时

You can divide seconds by 60 to get the minutes

import time
seconds = time.time()
minutes = seconds / 60
print(minutes)

When you divide it by 60 again, you will get the hours


回答 11


division = 3623 // 3600 #to hours
division2 = 600 // 60 #to minutes
print (division) #write hours
print (division2) #write minutes

PS我的代码不专业


division = 3623 // 3600 #to hours
division2 = 600 // 60 #to minutes
print (division) #write hours
print (division2) #write minutes

PS My code is unprofessional


查找两个嵌套列表的交集?

问题:查找两个嵌套列表的交集?

我知道如何得到两个平面列表的交集:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

要么

def intersect(a, b):
    return list(set(a) & set(b))

print intersect(b1, b2)

但是当我必须找到嵌套列表的交集时,我的问题就开始了:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

最后,我希望收到:

c3 = [[13,32],[7,13,28],[1,6]]

你们能帮我这个忙吗?

有关

I know how to get an intersection of two flat lists:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

or

def intersect(a, b):
    return list(set(a) & set(b))

print intersect(b1, b2)

But when I have to find intersection for nested lists then my problems starts:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

In the end I would like to receive:

c3 = [[13,32],[7,13,28],[1,6]]

Can you guys give me a hand with this?

Related


回答 0

如果你想:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [[13, 32], [7, 13, 28], [1,6]]

然后这是您的Python 2解决方案:

c3 = [filter(lambda x: x in c1, sublist) for sublist in c2]

在Python 3中,filter返回的是一个Iterable而不是list,因此您需要使用以下命令包装filter调用list()

c3 = [list(filter(lambda x: x in c1, sublist)) for sublist in c2]

说明:

过滤器部分接受每个子列表的项目,并检查它是否在源列表c1中。对c2中的每个子列表执行列表推导。

If you want:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [[13, 32], [7, 13, 28], [1,6]]

Then here is your solution for Python 2:

c3 = [filter(lambda x: x in c1, sublist) for sublist in c2]

In Python 3 filter returns an iterable instead of list, so you need to wrap filter calls with list():

c3 = [list(filter(lambda x: x in c1, sublist)) for sublist in c2]

Explanation:

The filter part takes each sublist’s item and checks to see if it is in the source list c1. The list comprehension is executed for each sublist in c2.


回答 1

您无需定义交集。它已经是场景的一流组成部分。

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> set(b1).intersection(b2)
set([4, 5])

You don’t need to define intersection. It’s already a first-class part of set.

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> set(b1).intersection(b2)
set([4, 5])

回答 2

对于只想查找两个列表的交集的人们,Asker提供了两种方法:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(b1, b2)

但是有一种更有效的混合方法,因为您只需要在列表/集合之间进行一次转换,而不是三种:

b1 = [1,2,3,4,5]
b2 = [3,4,5,6]
s2 = set(b2)
b3 = [val for val in b1 if val in s2]

这将在O(n)中运行,而他涉及列表理解的原始方法将在O(n ^ 2)中运行

For people just looking to find the intersection of two lists, the Asker provided two methods:

b1 = [1,2,3,4,5,9,11,15]
b2 = [4,5,6,7,8]
b3 = [val for val in b1 if val in b2]

and

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(b1, b2)

But there is a hybrid method that is more efficient, because you only have to do one conversion between list/set, as opposed to three:

b1 = [1,2,3,4,5]
b2 = [3,4,5,6]
s2 = set(b2)
b3 = [val for val in b1 if val in s2]

This will run in O(n), whereas his original method involving list comprehension will run in O(n^2)


回答 3

功能方法:

input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]

result = reduce(set.intersection, map(set, input_list))

它可以应用于1+列表的更一般情况

The functional approach:

input_list = [[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]

result = reduce(set.intersection, map(set, input_list))

and it can be applied to the more general case of 1+ lists


回答 4

纯列表理解版本

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> c1set = frozenset(c1)

展平变体:

>>> [n for lst in c2 for n in lst if n in c1set]
[13, 32, 7, 13, 28, 1, 6]

嵌套变体:

>>> [[n for n in lst if n in c1set] for lst in c2]
[[13, 32], [7, 13, 28], [1, 6]]

Pure list comprehension version

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> c1set = frozenset(c1)

Flatten variant:

>>> [n for lst in c2 for n in lst if n in c1set]
[13, 32, 7, 13, 28, 1, 6]

Nested variant:

>>> [[n for n in lst if n in c1set] for lst in c2]
[[13, 32], [7, 13, 28], [1, 6]]

回答 5

&运算符采用两组的交集。

{1, 2, 3} & {2, 3, 4}
Out[1]: {2, 3}

The & operator takes the intersection of two sets.

{1, 2, 3} & {2, 3, 4}
Out[1]: {2, 3}

回答 6

采取2个列表的交集的pythonic方法是:

[x for x in list1 if x in list2]

A pythonic way of taking the intersection of 2 lists is:

[x for x in list1 if x in list2]

回答 7

您应该使用此代码(取自http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks)进行拼合,该代码未经测试,但我确定它可以正常工作:


def flatten(x):
    """flatten(sequence) -> list

    Returns a single, flat list which contains all elements retrieved
    from the sequence and all recursively contained sub-sequences
    (iterables).

    Examples:
    >>> [1, 2, [3,4], (5,6)]
    [1, 2, [3, 4], (5, 6)]
    >>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)])
    [1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]"""

    result = []
    for el in x:
        #if isinstance(el, (list, tuple)):
        if hasattr(el, "__iter__") and not isinstance(el, basestring):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

展平列表后,可以按通常方式执行交集:


c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(flatten(c1), flatten(c2))

You should flatten using this code ( taken from http://kogs-www.informatik.uni-hamburg.de/~meine/python_tricks ), the code is untested, but I’m pretty sure it works:


def flatten(x):
    """flatten(sequence) -> list

    Returns a single, flat list which contains all elements retrieved
    from the sequence and all recursively contained sub-sequences
    (iterables).

    Examples:
    >>> [1, 2, [3,4], (5,6)]
    [1, 2, [3, 4], (5, 6)]
    >>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, MyVector(8,9,10)])
    [1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]"""

    result = []
    for el in x:
        #if isinstance(el, (list, tuple)):
        if hasattr(el, "__iter__") and not isinstance(el, basestring):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

After you had flattened the list, you perform the intersection in the usual way:


c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

def intersect(a, b):
     return list(set(a) & set(b))

print intersect(flatten(c1), flatten(c2))


回答 8

intersect定义以来,基本的列表理解就足够了:

>>> c3 = [intersect(c1, i) for i in c2]
>>> c3
[[32, 13], [28, 13, 7], [1, 6]]

得益于S. Lott的评论和TM。的相关评论:

>>> c3 = [list(set(c1).intersection(i)) for i in c2]
>>> c3
[[32, 13], [28, 13, 7], [1, 6]]

Since intersect was defined, a basic list comprehension is enough:

>>> c3 = [intersect(c1, i) for i in c2]
>>> c3
[[32, 13], [28, 13, 7], [1, 6]]

Improvement thanks to S. Lott’s remark and TM.’s associated remark:

>>> c3 = [list(set(c1).intersection(i)) for i in c2]
>>> c3
[[32, 13], [28, 13, 7], [1, 6]]

回答 9

鉴于:

> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

我发现以下代码运行良好,并且如果使用set操作,则可能更简洁:

> c3 = [list(set(f)&set(c1)) for f in c2] 

它得到:

> [[32, 13], [28, 13, 7], [1, 6]]

如果需要订购:

> c3 = [sorted(list(set(f)&set(c1))) for f in c2] 

我们有:

> [[13, 32], [7, 13, 28], [1, 6]]

顺便说一句,对于更多的python样式,这个也很好:

> c3 = [ [i for i in set(f) if i in c1] for f in c2]

Given:

> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

I find the following code works well and maybe more concise if using set operation:

> c3 = [list(set(f)&set(c1)) for f in c2] 

It got:

> [[32, 13], [28, 13, 7], [1, 6]]

If order needed:

> c3 = [sorted(list(set(f)&set(c1))) for f in c2] 

we got:

> [[13, 32], [7, 13, 28], [1, 6]]

By the way, for a more python style, this one is fine too:

> c3 = [ [i for i in set(f) if i in c1] for f in c2]

回答 10

我不知道我是否迟于回答你的问题。阅读完您的问题后,我想到了一个可在列表和嵌套列表上使用的函数intersect()。我使用递归来定义此功能,这非常直观。希望它是您要寻找的:

def intersect(a, b):
    result=[]
    for i in b:
        if isinstance(i,list):
            result.append(intersect(a,i))
        else:
            if i in a:
                 result.append(i)
    return result

例:

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> print intersect(c1,c2)
[[13, 32], [7, 13, 28], [1, 6]]

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> print intersect(b1,b2)
[4, 5]

I don’t know if I am late in answering your question. After reading your question I came up with a function intersect() that can work on both list and nested list. I used recursion to define this function, it is very intuitive. Hope it is what you are looking for:

def intersect(a, b):
    result=[]
    for i in b:
        if isinstance(i,list):
            result.append(intersect(a,i))
        else:
            if i in a:
                 result.append(i)
    return result

Example:

>>> c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
>>> c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
>>> print intersect(c1,c2)
[[13, 32], [7, 13, 28], [1, 6]]

>>> b1 = [1,2,3,4,5,9,11,15]
>>> b2 = [4,5,6,7,8]
>>> print intersect(b1,b2)
[4, 5]

回答 11

你考虑[1,2]相交[1, [2]]吗?也就是说,仅仅是您关心的数字还是列表结构?

如果只是数字,请研究如何“拉平”列表,然后使用该set()方法。

Do you consider [1,2] to intersect with [1, [2]]? That is, is it only the numbers you care about, or the list structure as well?

If only the numbers, investigate how to “flatten” the lists, then use the set() method.


回答 12

我也在寻找一种实现方法,最终它最终像这样:

def compareLists(a,b):
    removed = [x for x in a if x not in b]
    added = [x for x in b if x not in a]
    overlap = [x for x in a if x in b]
    return [removed,added,overlap]

I was also looking for a way to do it, and eventually it ended up like this:

def compareLists(a,b):
    removed = [x for x in a if x not in b]
    added = [x for x in b if x not in a]
    overlap = [x for x in a if x in b]
    return [removed,added,overlap]

回答 13

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

c3 = [list(set(c2[i]).intersection(set(c1))) for i in xrange(len(c2))]

c3
->[[32, 13], [28, 13, 7], [1, 6]]
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]

c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

c3 = [list(set(c2[i]).intersection(set(c1))) for i in xrange(len(c2))]

c3
->[[32, 13], [28, 13, 7], [1, 6]]

回答 14

我们可以为此使用set方法:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

   result = [] 
   for li in c2:
       res = set(li) & set(c1)
       result.append(list(res))

   print result

We can use set methods for this:

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]

   result = [] 
   for li in c2:
       res = set(li) & set(c1)
       result.append(list(res))

   print result

回答 15

要定义正确考虑元素基数的交集,请使用Counter

from collections import Counter

>>> c1 = [1, 2, 2, 3, 4, 4, 4]
>>> c2 = [1, 2, 4, 4, 4, 4, 5]
>>> list((Counter(c1) & Counter(c2)).elements())
[1, 2, 4, 4, 4]

To define intersection that correctly takes into account the cardinality of the elements use Counter:

from collections import Counter

>>> c1 = [1, 2, 2, 3, 4, 4, 4]
>>> c2 = [1, 2, 4, 4, 4, 4, 5]
>>> list((Counter(c1) & Counter(c2)).elements())
[1, 2, 4, 4, 4]

回答 16

# Problem:  Given c1 and c2:
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
# how do you get c3 to be [[13, 32], [7, 13, 28], [1, 6]] ?

这是一种c3不涉及集合的设置方法:

c3 = []
for sublist in c2:
    c3.append([val for val in c1 if val in sublist])

但是,如果您只想使用一行,则可以执行以下操作:

c3 = [[val for val in c1 if val in sublist]  for sublist in c2]

这是列表理解中的列表理解,这有点不寻常,但是我认为您在遵循它时应该不会有太多麻烦。

# Problem:  Given c1 and c2:
c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
# how do you get c3 to be [[13, 32], [7, 13, 28], [1, 6]] ?

Here’s one way to set c3 that doesn’t involve sets:

c3 = []
for sublist in c2:
    c3.append([val for val in c1 if val in sublist])

But if you prefer to use just one line, you can do this:

c3 = [[val for val in c1 if val in sublist]  for sublist in c2]

It’s a list comprehension inside a list comprehension, which is a little unusual, but I think you shouldn’t have too much trouble following it.


回答 17

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [list(set(i) & set(c1)) for i in c2]
c3
[[32, 13], [28, 13, 7], [1, 6]]

对我来说,这是一种非常优雅,快捷的方法:)

c1 = [1, 6, 7, 10, 13, 28, 32, 41, 58, 63]
c2 = [[13, 17, 18, 21, 32], [7, 11, 13, 14, 28], [1, 5, 6, 8, 15, 16]]
c3 = [list(set(i) & set(c1)) for i in c2]
c3
[[32, 13], [28, 13, 7], [1, 6]]

For me this is very elegant and quick way to to it :)


回答 18

平面清单可以reduce很容易地通过。

您需要使用初始化程序 -函数中的第三个参数reduce

reduce(
   lambda result, _list: result.append(
       list(set(_list)&set(c1)) 
     ) or result, 
   c2, 
   [])

上面的代码适用于python2和python3,但是您需要将reduce模块导入为from functools import reduce。有关详细信息,请参见下面的链接。

flat list can be made through reduce easily.

All you need to use initializer – third argument in the reduce function.

reduce(
   lambda result, _list: result.append(
       list(set(_list)&set(c1)) 
     ) or result, 
   c2, 
   [])

Above code works for both python2 and python3, but you need to import reduce module as from functools import reduce. Refer below link for details.


回答 19

查找可迭代对象之间的差异和交集的简单方法

如果重复很重要,请使用此方法

from collections import Counter

def intersection(a, b):
    """
    Find the intersection of two iterables

    >>> intersection((1,2,3), (2,3,4))
    (2, 3)

    >>> intersection((1,2,3,3), (2,3,3,4))
    (2, 3, 3)

    >>> intersection((1,2,3,3), (2,3,4,4))
    (2, 3)

    >>> intersection((1,2,3,3), (2,3,4,4))
    (2, 3)
    """
    return tuple(n for n, count in (Counter(a) & Counter(b)).items() for _ in range(count))

def difference(a, b):
    """
    Find the symmetric difference of two iterables

    >>> difference((1,2,3), (2,3,4))
    (1, 4)

    >>> difference((1,2,3,3), (2,3,4))
    (1, 3, 4)

    >>> difference((1,2,3,3), (2,3,4,4))
    (1, 3, 4, 4)
    """
    diff = lambda x, y: tuple(n for n, count in (Counter(x) - Counter(y)).items() for _ in range(count))
    return diff(a, b) + diff(b, a)

Simple way to find difference and intersection between iterables

Use this method if repetition matters

from collections import Counter

def intersection(a, b):
    """
    Find the intersection of two iterables

    >>> intersection((1,2,3), (2,3,4))
    (2, 3)

    >>> intersection((1,2,3,3), (2,3,3,4))
    (2, 3, 3)

    >>> intersection((1,2,3,3), (2,3,4,4))
    (2, 3)

    >>> intersection((1,2,3,3), (2,3,4,4))
    (2, 3)
    """
    return tuple(n for n, count in (Counter(a) & Counter(b)).items() for _ in range(count))

def difference(a, b):
    """
    Find the symmetric difference of two iterables

    >>> difference((1,2,3), (2,3,4))
    (1, 4)

    >>> difference((1,2,3,3), (2,3,4))
    (1, 3, 4)

    >>> difference((1,2,3,3), (2,3,4,4))
    (1, 3, 4, 4)
    """
    diff = lambda x, y: tuple(n for n, count in (Counter(x) - Counter(y)).items() for _ in range(count))
    return diff(a, b) + diff(b, a)

导入错误:没有模块名称urllib2

问题:导入错误:没有模块名称urllib2

这是我的代码:

import urllib2.request

response = urllib2.urlopen("http://www.google.com")
html = response.read()
print(html)

有什么帮助吗?

Here’s my code:

import urllib2.request

response = urllib2.urlopen("http://www.google.com")
html = response.read()
print(html)

Any help?


回答 0

urllib2文档中所述:

urllib2模块已在Python 3中分为几个名为urllib.request和的模块urllib.error2to3在将源转换为Python 3时,该工具将自动调整导入。

所以你应该说

from urllib.request import urlopen
html = urlopen("http://www.google.com/").read()
print(html)

您当前正在编辑的代码示例不正确,因为您是在说urllib.urlopen("http://www.google.com/")而不是urlopen("http://www.google.com/")

As stated in the urllib2 documentation:

The urllib2 module has been split across several modules in Python 3 named urllib.request and urllib.error. The 2to3 tool will automatically adapt imports when converting your sources to Python 3.

So you should instead be saying

from urllib.request import urlopen
html = urlopen("http://www.google.com/").read()
print(html)

Your current, now-edited code sample is incorrect because you are saying urllib.urlopen("http://www.google.com/") instead of just urlopen("http://www.google.com/").


回答 1

对于使用Python 2(测试版2.7.3和2.6.8)和Python 3(3.2.3和3.3.2+)的脚本,请尝试:

#! /usr/bin/env python

try:
    # For Python 3.0 and later
    from urllib.request import urlopen
except ImportError:
    # Fall back to Python 2's urllib2
    from urllib2 import urlopen

html = urlopen("http://www.google.com/")
print(html.read())

For a script working with Python 2 (tested versions 2.7.3 and 2.6.8) and Python 3 (3.2.3 and 3.3.2+) try:

#! /usr/bin/env python

try:
    # For Python 3.0 and later
    from urllib.request import urlopen
except ImportError:
    # Fall back to Python 2's urllib2
    from urllib2 import urlopen

html = urlopen("http://www.google.com/")
print(html.read())

回答 2

上面的内容在3.3中对我不起作用。改试试这个(YMMV等)

import urllib.request
url = "http://www.google.com/"
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
print (response.read().decode('utf-8'))

The above didn’t work for me in 3.3. Try this instead (YMMV, etc)

import urllib.request
url = "http://www.google.com/"
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
print (response.read().decode('utf-8'))

回答 3

一些制表符补全显示了Python 2 vs Python 3中软件包的内容。

在Python 2中:

In [1]: import urllib

In [2]: urllib.
urllib.ContentTooShortError      urllib.ftpwrapper                urllib.socket                    urllib.test1
urllib.FancyURLopener            urllib.getproxies                urllib.splitattr                 urllib.thishost
urllib.MAXFTPCACHE               urllib.getproxies_environment    urllib.splithost                 urllib.time
urllib.URLopener                 urllib.i                         urllib.splitnport                urllib.toBytes
urllib.addbase                   urllib.localhost                 urllib.splitpasswd               urllib.unquote
urllib.addclosehook              urllib.noheaders                 urllib.splitport                 urllib.unquote_plus
urllib.addinfo                   urllib.os                        urllib.splitquery                urllib.unwrap
urllib.addinfourl                urllib.pathname2url              urllib.splittag                  urllib.url2pathname
urllib.always_safe               urllib.proxy_bypass              urllib.splittype                 urllib.urlcleanup
urllib.base64                    urllib.proxy_bypass_environment  urllib.splituser                 urllib.urlencode
urllib.basejoin                  urllib.quote                     urllib.splitvalue                urllib.urlopen
urllib.c                         urllib.quote_plus                urllib.ssl                       urllib.urlretrieve
urllib.ftpcache                  urllib.re                        urllib.string                    
urllib.ftperrors                 urllib.reporthook                urllib.sys  

在Python 3中:

In [2]: import urllib.
urllib.error        urllib.parse        urllib.request      urllib.response     urllib.robotparser

In [2]: import urllib.error.
urllib.error.ContentTooShortError  urllib.error.HTTPError             urllib.error.URLError

In [2]: import urllib.parse.
urllib.parse.parse_qs          urllib.parse.quote_plus        urllib.parse.urldefrag         urllib.parse.urlsplit
urllib.parse.parse_qsl         urllib.parse.unquote           urllib.parse.urlencode         urllib.parse.urlunparse
urllib.parse.quote             urllib.parse.unquote_plus      urllib.parse.urljoin           urllib.parse.urlunsplit
urllib.parse.quote_from_bytes  urllib.parse.unquote_to_bytes  urllib.parse.urlparse

In [2]: import urllib.request.
urllib.request.AbstractBasicAuthHandler         urllib.request.HTTPSHandler
urllib.request.AbstractDigestAuthHandler        urllib.request.OpenerDirector
urllib.request.BaseHandler                      urllib.request.ProxyBasicAuthHandler
urllib.request.CacheFTPHandler                  urllib.request.ProxyDigestAuthHandler
urllib.request.DataHandler                      urllib.request.ProxyHandler
urllib.request.FTPHandler                       urllib.request.Request
urllib.request.FancyURLopener                   urllib.request.URLopener
urllib.request.FileHandler                      urllib.request.UnknownHandler
urllib.request.HTTPBasicAuthHandler             urllib.request.build_opener
urllib.request.HTTPCookieProcessor              urllib.request.getproxies
urllib.request.HTTPDefaultErrorHandler          urllib.request.install_opener
urllib.request.HTTPDigestAuthHandler            urllib.request.pathname2url
urllib.request.HTTPErrorProcessor               urllib.request.url2pathname
urllib.request.HTTPHandler                      urllib.request.urlcleanup
urllib.request.HTTPPasswordMgr                  urllib.request.urlopen
urllib.request.HTTPPasswordMgrWithDefaultRealm  urllib.request.urlretrieve
urllib.request.HTTPRedirectHandler     


In [2]: import urllib.response.
urllib.response.addbase       urllib.response.addclosehook  urllib.response.addinfo       urllib.response.addinfourl

Some tab completions to show the contents of the packages in Python 2 vs Python 3.

In Python 2:

In [1]: import urllib

In [2]: urllib.
urllib.ContentTooShortError      urllib.ftpwrapper                urllib.socket                    urllib.test1
urllib.FancyURLopener            urllib.getproxies                urllib.splitattr                 urllib.thishost
urllib.MAXFTPCACHE               urllib.getproxies_environment    urllib.splithost                 urllib.time
urllib.URLopener                 urllib.i                         urllib.splitnport                urllib.toBytes
urllib.addbase                   urllib.localhost                 urllib.splitpasswd               urllib.unquote
urllib.addclosehook              urllib.noheaders                 urllib.splitport                 urllib.unquote_plus
urllib.addinfo                   urllib.os                        urllib.splitquery                urllib.unwrap
urllib.addinfourl                urllib.pathname2url              urllib.splittag                  urllib.url2pathname
urllib.always_safe               urllib.proxy_bypass              urllib.splittype                 urllib.urlcleanup
urllib.base64                    urllib.proxy_bypass_environment  urllib.splituser                 urllib.urlencode
urllib.basejoin                  urllib.quote                     urllib.splitvalue                urllib.urlopen
urllib.c                         urllib.quote_plus                urllib.ssl                       urllib.urlretrieve
urllib.ftpcache                  urllib.re                        urllib.string                    
urllib.ftperrors                 urllib.reporthook                urllib.sys  

In Python 3:

In [2]: import urllib.
urllib.error        urllib.parse        urllib.request      urllib.response     urllib.robotparser

In [2]: import urllib.error.
urllib.error.ContentTooShortError  urllib.error.HTTPError             urllib.error.URLError

In [2]: import urllib.parse.
urllib.parse.parse_qs          urllib.parse.quote_plus        urllib.parse.urldefrag         urllib.parse.urlsplit
urllib.parse.parse_qsl         urllib.parse.unquote           urllib.parse.urlencode         urllib.parse.urlunparse
urllib.parse.quote             urllib.parse.unquote_plus      urllib.parse.urljoin           urllib.parse.urlunsplit
urllib.parse.quote_from_bytes  urllib.parse.unquote_to_bytes  urllib.parse.urlparse

In [2]: import urllib.request.
urllib.request.AbstractBasicAuthHandler         urllib.request.HTTPSHandler
urllib.request.AbstractDigestAuthHandler        urllib.request.OpenerDirector
urllib.request.BaseHandler                      urllib.request.ProxyBasicAuthHandler
urllib.request.CacheFTPHandler                  urllib.request.ProxyDigestAuthHandler
urllib.request.DataHandler                      urllib.request.ProxyHandler
urllib.request.FTPHandler                       urllib.request.Request
urllib.request.FancyURLopener                   urllib.request.URLopener
urllib.request.FileHandler                      urllib.request.UnknownHandler
urllib.request.HTTPBasicAuthHandler             urllib.request.build_opener
urllib.request.HTTPCookieProcessor              urllib.request.getproxies
urllib.request.HTTPDefaultErrorHandler          urllib.request.install_opener
urllib.request.HTTPDigestAuthHandler            urllib.request.pathname2url
urllib.request.HTTPErrorProcessor               urllib.request.url2pathname
urllib.request.HTTPHandler                      urllib.request.urlcleanup
urllib.request.HTTPPasswordMgr                  urllib.request.urlopen
urllib.request.HTTPPasswordMgrWithDefaultRealm  urllib.request.urlretrieve
urllib.request.HTTPRedirectHandler     


In [2]: import urllib.response.
urllib.response.addbase       urllib.response.addclosehook  urllib.response.addinfo       urllib.response.addinfourl

回答 4

Python 3:

import urllib.request

wp = urllib.request.urlopen("http://google.com")
pw = wp.read()
print(pw)

Python 2:

import urllib
import sys

wp = urllib.urlopen("http://google.com")
for line in wp:
    sys.stdout.write(line)

虽然我已经测试了各自版本中的两个代码。

Python 3:

import urllib.request

wp = urllib.request.urlopen("http://google.com")
pw = wp.read()
print(pw)

Python 2:

import urllib
import sys

wp = urllib.urlopen("http://google.com")
for line in wp:
    sys.stdout.write(line)

While I have tested both the Codes in respective versions.


回答 5

所有解决方案中最简单的:

在Python 3.x中:

import urllib.request
url = "https://api.github.com/users?since=100"
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
data_content = response.read()
print(data_content)

Simplest of all solutions:

In Python 3.x:

import urllib.request
url = "https://api.github.com/users?since=100"
request = urllib.request.Request(url)
response = urllib.request.urlopen(request)
data_content = response.read()
print(data_content)

回答 6

在python 3中,要获取文本输出:

import io
import urllib.request

response = urllib.request.urlopen("http://google.com")
text = io.TextIOWrapper(response)

In python 3, to get text output:

import io
import urllib.request

response = urllib.request.urlopen("http://google.com")
text = io.TextIOWrapper(response)

回答 7

那在python3中对我有用:

import urllib.request
htmlfile = urllib.request.urlopen("http://google.com")
htmltext = htmlfile.read()
print(htmltext)

That worked for me in python3:

import urllib.request
htmlfile = urllib.request.urlopen("http://google.com")
htmltext = htmlfile.read()
print(htmltext)