标签归档:python-3.x

无法在ubuntu中将默认python版本设置为python3

问题:无法在ubuntu中将默认python版本设置为python3

我试图将默认python版本设置为python3in Ubuntu 16.04。默认情况下为python2(2.7)。我遵循以下步骤:

update-alternatives --remove python /usr/bin/python2
update-alternatives --install /usr/bin/python python /usr/bin/python3

但是第二条语句出现以下错误,

rejeesh@rejeesh-Vostro-1015:~$ update-alternatives --install /usr/bin/python python /usr/bin/python3
update-alternatives: --install needs <link> <name> <path> <priority>

Use 'update-alternatives --help' for program usage information.   

我是Ubuntu的新手,我不知道自己在做什么错。

I was trying to set default python version to python3 in Ubuntu 16.04. By default it is python2 (2.7). I followed below steps :

update-alternatives --remove python /usr/bin/python2
update-alternatives --install /usr/bin/python python /usr/bin/python3

but I’m getting the following error for the second statement,

rejeesh@rejeesh-Vostro-1015:~$ update-alternatives --install /usr/bin/python python /usr/bin/python3
update-alternatives: --install needs <link> <name> <path> <priority>

Use 'update-alternatives --help' for program usage information.   

I’m new to Ubuntu and Idon’t know what I’m doing wrong.


回答 0

打开您的.bashrc文件nano ~/.bashrcalias python=python3在文件顶部的新行上键入,然后使用ctrl + o保存文件并使用ctrl + x关闭文件。然后,返回您的命令行类型source ~/.bashrc。现在,您的别名应该是永久的。

编辑:

对于更新替代方案,优先级是整数。优先级表示应该首先使用哪个程序。文章总结说起来相当不错。

EDIT:

I wrote this when I was young an naive, update-alternatives is the better way to do this. See @Pardhu’s answer.

Open your .bashrc file nano ~/.bashrc. Type alias python=python3 on to a new line at the top of the file then save the file with ctrl+o and close the file with ctrl+x. Then, back at your command line type source ~/.bashrc. Now your alias should be permanent.


回答 1

提到的第二行可以更改为

update-alternatives --install /usr/bin/python python /usr/bin/python3 10

的路径优先级为10 python3。编辑.bashrc文件的缺点是,当与结合使用命令时,它将不起作用sudo

更新:sudo在运行以下命令时使用:

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10

The second line mentioned can be changed to

update-alternatives --install /usr/bin/python python /usr/bin/python3 10

This gives a priority of 10 for the path of python3. The disadvantage of editing .bashrc file is that it will not work while using the commands with sudo.

Update: Please use sudo while running the command like this:

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 10


回答 2

将Ubuntu 3.04中的默认Python 3.6.8更改为Python 3.7。

安装Python 3.7

安装Python3.7并将其配置为默认解释器的步骤。

  1. 使用apt-get安装python3.7软件包

    sudo apt-get install python3.7

  2. 将Python3.6和Python 3.7添加到 update-alternatives

sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2
  1. 更新Python 3以指向Python 3.7

    sudo update-alternatives --config python3 为Python 3.7输入2

  2. 测试python版本

python3 --v
Python 3.7.1 

To change Python 3.6.8 as the default in Ubuntu 18.04 to Python 3.7.

Install Python 3.7

Steps to install Python3.7 and configure it as the default interpreter.

  1. Install the python3.7 package using apt-get

    sudo apt-get install python3.7

  2. Add Python3.6 & Python 3.7 to update-alternatives

sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1
sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2
  1. Update Python 3 to point to Python 3.7

    sudo update-alternatives --config python3 Enter 2 for Python 3.7

  2. Test the version of python

python3 --version
Python 3.7.1 

回答 3

要更改为python3,可以在terminal中使用以下命令alias python=python3

To change to python3, you can use the following command in terminal alias python=python3.


回答 4

一种简单安全的方法是使用别名。将其放入〜/ .bashrc文件中:如果您使用gedit编辑器

gedit〜/ .bashrc

进入bashrc文件,然后在bashrc文件的顶部进行以下更改。

别名python = python3

在文件中添加以上内容之后。运行以下命令

源〜/ .bash_aliases或源〜/ .bashrc

例:

$ python-版本

Python 2.7.6

$ python3-版本

Python 3.4.3

$别名python = python3

$ python-版本

Python 3.4.3

A simple safe way would be to use an alias. Place this into ~/.bashrc file: if you have gedit editor use

gedit ~/.bashrc

to go into the bashrc file and then at the top of the bashrc file make the following change.

alias python=python3

After adding the above in the file. run the below command

source ~/.bash_aliases or source ~/.bashrc

example:

$ python –version

Python 2.7.6

$ python3 –version

Python 3.4.3

$ alias python=python3

$ python –version

Python 3.4.3


回答 5

另外,您还可以为pip添加一个别名(在.bashrc或bash_aliases中):

别名pip =’pip3′

许多人发现python3的全新安装实际上指向python3.x,因此您可能需要:

别名pip =’pip3.6′
别名python =’python3.6′

As an added extra, you can add an alias for pip as well (in .bashrc or bash_aliases):

alias pip=’pip3′

You many find that a clean install of python3 actually points to python3.x so you may need:

alias pip=’pip3.6′
alias python=’python3.6′


回答 6

首先安装python3和pip3

sudo apt-get install python3 python3-pip

然后在终端运行

alias python=python3

检查计算机中的python版本。

python --version

At First Install python3 and pip3

sudo apt-get install python3 python3-pip

then in your terminal run

alias python=python3

Check the version of python in your machine.

python --version

回答 7

如果您具有Ubuntu Focal(20.20),则可以安装python-is-python3

sudo apt-get install python-is-python3

替换符号链接/usr/bin/python以指向/usr/bin/python3.8

If you have Ubuntu 20.04 LTS (Focal Fossa) you can install python-is-python3:

sudo apt install python-is-python3

which replaces the symlink in /usr/bin/python to point to /usr/bin/python3.


回答 8

就像说的那样 update-alternatives --install需要<link> <name> <path>和<priority>参数。

您具有链接(/usr/bin/python),名称(python)和路径(/usr/bin/python3),但缺少优先级。

update-alternatives --help 说:

<priority>是整数;数字更大的选项在自动模式下具有更高的优先级。

所以100在末尾放一个

As it says, update-alternatives --install needs <link> <name> <path> and <priority> arguments.

You have link (/usr/bin/python), name (python), and path (/usr/bin/python3), you’re missing priority.

update-alternatives --help says:

<priority> is an integer; options with higher numbers have higher priority in automatic mode.

So just put a 100 or something at the end


回答 9

cd ~
gedit .bash_aliases

然后写

alias python=python3

要么

alias python='/usr/bin/python3'

保存文件,关闭终端,然后再次打开。
您现在应该很好!链接

Do

cd ~
gedit .bash_aliases

then write either

alias python=python3

or

alias python='/usr/bin/python3'

Save the file, close the terminal and open it again.
You should be fine now! Link


回答 10

只需按照以下步骤操作,即可将默认python更改为新升级的python版本。对我来说很好。

  • sudo apt-install python3.7 安装所需的最新版本的python
  • cd /usr/bin 输入安装了python的根目录
  • sudo unlink pythonsudo unlink python3。取消链接当前的默认python
  • sudo ln -sv /usr/bin/python3.7 python 链接新下载的python版本
  • python --version 检查新的python版本,您一切顺利

Just follow these steps to help change the default python to the newly upgrade python version. Worked well for me.

  • sudo apt-install python3.7 Install the latest version of python you want
  • cd /usr/bin Enter the root directory where python is installed
  • sudo unlink python or sudo unlink python3 . Unlink the current default python
  • sudo ln -sv /usr/bin/python3.7 python Link the new downloaded python version
  • python --version Check the new python version and you’re good to go

回答 11

对于另一种仅限于当前用户的非侵入式方法:

# First, make $HOME/bin, which will be automatically added to user's PATH
mkdir -p ~/bin
# make link actual python binaries
ln -s $(which python3) python
ln -s $(which pip3) pip

python pip 将在新的外壳中准备好。

For another non-invasive, current-user only approach:

# First, make $HOME/bin, which will be automatically added to user's PATH
mkdir -p ~/bin
# make link actual python binaries
ln -s $(which python3) python
ln -s $(which pip3) pip

python pip will be ready in a new shell.


回答 12

从获取python路径

ls /usr/bin/python*

然后设置你的python版本

alias python="/usr/bin/python3"

get python path from

ls /usr/bin/python*

then set your python version

alias python="/usr/bin/python3"

回答 13

适用于所有用户的ubuntu 18.04中的最佳方法是

sudo vim /etc/bash.bashrc
add lines
alias python=python3
alias pip=pip3

保存更改并重新启动。

重新启动后,系统中的python 3版本以及python 2.7都将作为默认版本。如果您使用的是python 3的多个版本,则可以通过在别名中说以下内容来更加具体。

sudo vim /etc/bash.bashrc
add lines
alias python=python3.6
alias pip=pip3.6

The best way in ubuntu 18.04 which will work for all users is

sudo vim /etc/bash.bashrc
add lines
alias python=python3
alias pip=pip3

Save the changes and restart .

After restart what ever version of python 3 you have in the system along with python 2.7 will be taken as default. You could be more specific by saying the following in alias if you have multiple version of python 3.

sudo vim /etc/bash.bashrc
add lines
alias python=python3.6
alias pip=pip3.6

回答 14

只需删除python-is-python2

sudo apt purge python-is-python2

并安装python-is-python3

sudo apt install python-is-python3

它将自动过渡到新的python3。(可选)您可以稍后删除其余软件包:

sudo apt autoremove && sudo apt autoclean

Simply remove python-is-python2:

sudo apt purge python-is-python2

And install python-is-python3:

sudo apt install python-is-python3

It will automate the process of transition to new python3. Optionally you can get rid of remaining packages later:

sudo apt autoremove && sudo apt autoclean

回答 15

要将Python 3.6.8从Python 2.7更改为Ubuntu 18.04中的默认设置,可以尝试使用命令行工具update-alternatives

sudo update-alternatives --config python

如果出现错误“ python没有替代品”,请使用以下命令自己设置替代品:

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2

相应地将路径更改为/usr/bin/python3所需的python版本。

优先级指定的最后一个参数表示,如果未进行手动替代选择,则将设置优先级最高的替代项。在我们的示例中,我们为设置了优先级2,/usr/bin/python3.6.8因此/usr/bin/python3.6.8update-alternatives命令自动将其设置为默认python版本。

我们可以随时使用以下命令在上面列出的python替代版本之间切换,并输入选择编号:

update-alternatives --config python

To change Python 3.6.8 as the default in Ubuntu 18.04 from Python 2.7 you can try the command line tool update-alternatives.

sudo update-alternatives --config python

If you get the error “no alternatives for python” then set up an alternative yourself with the following command:

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 2

Change the path /usr/bin/python3 to your desired python version accordingly.

The last argument specified it priority means, if no manual alternative selection is made the alternative with the highest priority number will be set. In our case we have set a priority 2 for /usr/bin/python3.6.8 and as a result the /usr/bin/python3.6.8 was set as default python version automatically by update-alternatives command.

we can anytime switch between the above listed python alternative versions using below command and entering a selection number:

update-alternatives --config python

回答 16

首先,确保您的计算机上安装了Python3

转到终端并输入:

cd ~/ 转到您的主目录

如果尚未设置,请.bash_profile键入touch .bash_profile以创建.bash_profile。

或者,键入open -e .bash_profile以编辑文件。

复制并保存alias python=python3在.bash_profile中。

关闭并重新打开您的终端。然后键入以下命令以检查是否 Python3现在是您的默认版本:

python --version

您应该看到python 3.xy是您的默认版本。

干杯!

At first, Make sure Python3 is installed on your computer

Go to your terminal and type:

cd ~/ to go to your home directory

If you didn’t set up your .bash_profile yet, type touch .bash_profile to create your .bash_profile.

Or, type open -e .bash_profile to edit the file.

Copy and save alias python=python3 in the .bash_profile.

Close and reopen your Terminal. Then type the following command to check if Python3 is your default version now:

python --version

You should see python 3.x.y is your default version.

Cheers!


python中有内置的标识函数吗?

问题:python中有内置的标识函数吗?

我想指出一个什么都不做的函数:

def identity(*args)
    return args

我的用例是这样的

try:
    gettext.find(...)
    ...
    _ = gettext.gettext
else:
    _ = identity

当然,我可以使用identity上面定义的方法,但是内置方法肯定会运行得更快(并避免我自己引入的错误)​​。

显然,mapfilter使用None的身份,但这是具体到它们的实现。

>>> _=None
>>> _("hello")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable

I’d like to point to a function that does nothing:

def identity(*args)
    return args

my use case is something like this

try:
    gettext.find(...)
    ...
    _ = gettext.gettext
else:
    _ = identity

Of course, I could use the identity defined above, but a built-in would certainly run faster (and avoid bugs introduced by my own).

Apparently, map and filter use None for the identity, but this is specific to their implementations.

>>> _=None
>>> _("hello")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not callable

回答 0

做更多的研究,没有,没有一个功能,问题1673203被问到。来自Raymond Hettinger表示不会

最好让人们自己编写琐碎的传递,并考虑签名和时间成本。

因此实际上是一个更好的方法(lambda避免为函数命名):

_ = lambda *args: args
  • 优点:可以使用任意数量的参数
  • 缺点:结果是参数的盒装版本

要么

_ = lambda x: x
  • 优点:不会改变参数的类型
  • 缺点:只能使用1个位置参数

Doing some more research, there is none, a feature was asked in issue 1673203 And from Raymond Hettinger said there won’t be:

Better to let people write their own trivial pass-throughs and think about the signature and time costs.

So a better way to do it is actually (a lambda avoids naming the function):

_ = lambda *args: args
  • advantage: takes any number of parameters
  • disadvantage: the result is a boxed version of the parameters

OR

_ = lambda x: x
  • advantage: doesn’t change the type of the parameter
  • disadvantage: takes exactly 1 positional parameter

回答 1

https://en.wikipedia.org/wiki/Identity_function中定义的身份函数,它采用单个参数并返回不变:

def identity(x):
    return x

你要签名什么你问,当你说的def identity(*args)不是严格意义上的标识功能,只要你想它采取多个参数。很好,但是随后您遇到了一个问题,因为Python函数不会返回多个结果,因此您必须找到一种将所有这些参数塞入一个返回值的方法。

在Python中返回“多个值”的通常方法是返回值的元组-从技术上讲,这是一个返回值,但它可以在大多数情况下使用,就好像它是多个值一样。但是在这里做意味着你得到

>>> def mv_identity(*args):
...     return args
...
>>> mv_identity(1,2,3)
(1, 2, 3)
>>> # So far, so good. But what happens now with single arguments?
>>> mv_identity(1)
(1,)

快速解决问题会带来其他问题,如此处所示的各种答案。

因此,总而言之,Python中没有定义身份函数,因为:

  1. 形式定义(单个参数函数)不是那么有用,并且编写起来很简单。
  2. 通常,将定义扩展到多个参数的定义不是很好,因此最好定义自己的版本,使其适合您的特定情况。

为了您的确切情况,

def dummy_gettext(message):
    return message

几乎可以肯定是您想要的-一个具有相同的调用约定和return的函数,gettext.gettext该函数不变地返回其参数,并被明确命名以描述其作用以及打算在何处使用。如果性能在这里是至关重要的考虑因素,我会感到非常震惊。

An identity function, as defined in https://en.wikipedia.org/wiki/Identity_function, takes a single argument and returns it unchanged:

def identity(x):
    return x

What you are asking for when you say you want the signature def identity(*args) is not strictly an identity function, as you want it to take multiple arguments. That’s fine, but then you hit a problem as Python functions don’t return multiple results, so you have to find a way of cramming all of those arguments into one return value.

The usual way of returning “multiple values” in Python is to return a tuple of the values – technically that’s one return value but it can be used in most contexts as if it were multiple values. But doing that here means you get

>>> def mv_identity(*args):
...     return args
...
>>> mv_identity(1,2,3)
(1, 2, 3)
>>> # So far, so good. But what happens now with single arguments?
>>> mv_identity(1)
(1,)

And fixing that problem quickly gives other issues, as the various answers here have shown.

So, in summary, there’s no identity function defined in Python because:

  1. The formal definition (a single argument function) isn’t that useful, and is trivial to write.
  2. Extending the definition to multiple arguments is not well-defined in general, and you’re far better off defining your own version that works the way you need it to for your particular situation.

For your precise case,

def dummy_gettext(message):
    return message

is almost certainly what you want – a function that has the same calling convention and return as gettext.gettext, which returns its argument unchanged, and is clearly named to describe what it does and where it’s intended to be used. I’d be pretty shocked if performance were a crucial consideration here.


回答 2

你的会很好的。当参数数量固定后,您可以使用如下匿名函数:

lambda x: x

yours will work fine. When the number of parameters is fix you can use an anonymous function like this:

lambda x: x

回答 3

Python中没有内置的标识函数。Haskell id函数的模仿为:

identity = lambda x, *args: (x,) + args if args else x

用法示例:

identity(1)
1
identity(1,2)
(1, 2)

由于identity除了返回给定的参数外什么都不做,因此我认为它不会比本机实现慢。

There is no a built-in identity function in Python. An imitation of the Haskell’s id function would be:

identity = lambda x, *args: (x,) + args if args else x

Example usage:

identity(1)
1
identity(1,2)
(1, 2)

Since identity does nothing except returning the given arguments, I do not think that it is slower than a native implementation would be.


回答 4

不,没有。

请注意,您的identity

  1. 等价于lambda * args:args
  2. 将装箱参数-即

    In [6]: id = lambda *args: args
    
    In [7]: id(3)
    Out[7]: (3,)

因此,lambda arg: arg如果您需要真正的身份功能,则可能要使用。

注意:此示例将隐藏内置id函数(您可能永远不会使用)。

No, there isn’t.

Note that your identity:

  1. is equivalent to lambda *args: args
  2. Will box its args – i.e.

    In [6]: id = lambda *args: args
    
    In [7]: id(3)
    Out[7]: (3,)
    

So, you may want to use lambda arg: arg if you want a true identity function.

NB: This example will shadow the built-in id function (which you will probably never use).


回答 5

如果速度无关紧要,则应该处理所有情况:

def identity(*args, **kwargs):
    if not args:
        if not kwargs:
            return None
        elif len(kwargs) == 1:
            return  next(iter(kwargs.values()))
        else:
            return (*kwargs.values(),)
    elif not kwargs:
        if len(args) == 1:
            return args[0]
        else:
            return args
    else:
        return (*args, *kwargs.values())

用法示例:

print(identity())
None
$identity(1)
1
$ identity(1, 2)
(1, 2)
$ identity(1, b=2)
(1, 2)
$ identity(a=1, b=2)
(1, 2)
$ identity(1, 2, c=3)
(1, 2, 3)

If the speed does not matter, this should handle all cases:

def identity(*args, **kwargs):
    if not args:
        if not kwargs:
            return None
        elif len(kwargs) == 1:
            return  next(iter(kwargs.values()))
        else:
            return (*kwargs.values(),)
    elif not kwargs:
        if len(args) == 1:
            return args[0]
        else:
            return args
    else:
        return (*args, *kwargs.values())

Examples of usage:

print(identity())
None
$identity(1)
1
$ identity(1, 2)
(1, 2)
$ identity(1, b=2)
(1, 2)
$ identity(a=1, b=2)
(1, 2)
$ identity(1, 2, c=3)
(1, 2, 3)

回答 6

单参数函数的存根

gettext.gettext(OP的示例用例)接受单个参数message。如果一个人需要为它存根,没有理由退换货[message],而不是messagedef identity(*args): return args)。因此两者

_ = lambda message: message

def _(message):
    return message

伏贴。

…但是内置程序肯定会运行得更快(并避免我自己引入的错误)​​。

在这种琐碎的情况下,错误几乎无关紧要。对于预定义类型的参数,例如str,我们可以将str()其自身用作身份函数(因为通过字符串进行交互,它甚至保留了对象身份,请参见id下面的注释),并将其性能与lambda解决方案进行比较:

$ python3 -m timeit -s "f = lambda m: m" "f('foo')"
10000000 loops, best of 3: 0.0852 usec per loop
$ python3 -m timeit "str('foo')"
10000000 loops, best of 3: 0.107 usec per loop

微优化是可能的。例如,以下Cython代码:

test.pyx

cpdef str f(str message):
    return message

然后:

$ pip install runcython3
$ makecython3 test.pyx
$ python3 -m timeit -s "from test import f" "f('foo')"
10000000 loops, best of 3: 0.0317 usec per loop

内置对象识别功能

不要将身份函数与id返回对象“身份”的内置函数(该对象的唯一标识符,而不是与==运算符相比,该对象的值,而不是该对象的值)相混淆,后者是CPython中的内存地址。

Stub of a single-argument function

gettext.gettext (the OP’s example use case) accepts a single argument, message. If one needs a stub for it, there’s no reason to return [message] instead of message (def identity(*args): return args). Thus both

_ = lambda message: message

def _(message):
    return message

fit perfectly.

…but a built-in would certainly run faster (and avoid bugs introduced by my own).

Bugs in such a trivial case are barely relevant. For an argument of predefined type, say str, we can use str() itself as an identity function (because of string interning it even retains object identity, see id note below) and compare its performance with the lambda solution:

$ python3 -m timeit -s "f = lambda m: m" "f('foo')"
10000000 loops, best of 3: 0.0852 usec per loop
$ python3 -m timeit "str('foo')"
10000000 loops, best of 3: 0.107 usec per loop

A micro-optimisation is possible. For example, the following Cython code:

test.pyx

cpdef str f(str message):
    return message

Then:

$ pip install runcython3
$ makecython3 test.pyx
$ python3 -m timeit -s "from test import f" "f('foo')"
10000000 loops, best of 3: 0.0317 usec per loop

Build-in object identity function

Don’t confuse an identity function with the id built-in function which returns the ‘identity’ of an object (meaning a unique identifier for that particular object rather than that object’s value, as compared with == operator), its memory address in CPython.


回答 7

线程很旧。但是仍然想发布这个。

可以为参数和对象建立身份方法。在下面的示例中,ObjOut是ObjIn的标识。上面所有其他示例都没有处理dict ** wargs。

class test(object):
    def __init__(self,*args,**kwargs):
        self.args = args
        self.kwargs = kwargs
    def identity (self):
        return self

objIn=test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n')
objOut=objIn.identity()
print('args=',objOut.args,'kwargs=',objOut.kwargs)

#If you want just the arguments to be printed...
print(test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n').identity().args)
print(test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n').identity().kwargs)

$ py test.py
args= ('arg-1', 'arg-2', 'arg-3', 'arg-n') kwargs= {'key1': 1, 'keyn': 'n', 'key2': 2, 'key3': 3}
('arg-1', 'arg-2', 'arg-3', 'arg-n')
{'key1': 1, 'keyn': 'n', 'key2': 2, 'key3': 3}

The thread is pretty old. But still wanted to post this.

It is possible to build an identity method for both arguments and objects. In the example below, ObjOut is an identity for ObjIn. All other examples above haven’t dealt with dict **kwargs.

class test(object):
    def __init__(self,*args,**kwargs):
        self.args = args
        self.kwargs = kwargs
    def identity (self):
        return self

objIn=test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n')
objOut=objIn.identity()
print('args=',objOut.args,'kwargs=',objOut.kwargs)

#If you want just the arguments to be printed...
print(test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n').identity().args)
print(test('arg-1','arg-2','arg-3','arg-n',key1=1,key2=2,key3=3,keyn='n').identity().kwargs)

$ py test.py
args= ('arg-1', 'arg-2', 'arg-3', 'arg-n') kwargs= {'key1': 1, 'keyn': 'n', 'key2': 2, 'key3': 3}
('arg-1', 'arg-2', 'arg-3', 'arg-n')
{'key1': 1, 'keyn': 'n', 'key2': 2, 'key3': 3}

如何在Windows上的Python 3中连接到MySQL?

问题:如何在Windows上的Python 3中连接到MySQL?

我在Windows上使用ActiveState Python 3,并想连接到我的MySQL数据库。我听说这mysqldb是要使用的模块。我找不到mysqldbPython 3。

有二进制文件存在的存储库mysqldb吗?如何在Windows的Python 3中连接到MySQL?

I am using ActiveState Python 3 on Windows and wanted to connect to my MySQL database. I heard that mysqldb was the module to use. I can’t find mysqldb for Python 3.

Is there a repository available where the binaries exist for mysqldb? How can I connect to MySQL in Python 3 on Windows?


回答 0

当前有一些将python 3与mysql结合使用的选项:

https://pypi.python.org/pypi/mysql-connector-python

  • 由Oracle官方支持
  • 纯Python
  • 有点慢
  • 与MySQLdb不兼容

https://pypi.python.org/pypi/pymysql

  • 纯Python
  • 比mysql-connector快
  • MySQLdb调用后几乎与完全兼容pymysql.install_as_MySQLdb()

https://pypi.python.org/pypi/cymysql

  • pymysql的fork与可选的C加速

https://pypi.python.org/pypi/mysqlclient

  • Django推荐的库。
  • 原始MySQLdb的友好分支,希望有一天能合并
  • 最快的实现,因为它基于C。
  • 与MySQLdb最兼容,因为它是一个fork
  • Debian和Ubuntu使用它来提供python-mysqldbpython3-mysqldb软件包。

此处的基准测试:https//github.com/methane/mysql-driver-benchmarks

There are currently a few options for using Python 3 with mysql:

https://pypi.python.org/pypi/mysql-connector-python

  • Officially supported by Oracle
  • Pure python
  • A little slow
  • Not compatible with MySQLdb

https://pypi.python.org/pypi/pymysql

  • Pure python
  • Faster than mysql-connector
  • Almost completely compatible with MySQLdb, after calling pymysql.install_as_MySQLdb()

https://pypi.python.org/pypi/cymysql

  • fork of pymysql with optional C speedups

https://pypi.python.org/pypi/mysqlclient

  • Django’s recommended library.
  • Friendly fork of the original MySQLdb, hopes to merge back some day
  • The fastest implementation, as it is C based.
  • The most compatible with MySQLdb, as it is a fork
  • Debian and Ubuntu use it to provide both python-mysqldb andpython3-mysqldb packages.

benchmarks here: https://github.com/methane/mysql-driver-benchmarks


回答 1

您可能应该使用pymysql-纯Python MySQL客户端
它与Python 3.x兼容,并且没有任何依赖关系。

这个纯Python MySQL客户端通过二进制客户端/服务器协议直接与服务器通信,从而为MySQL数据库提供DB-API。

例:

import pymysql
conn = pymysql.connect(host='127.0.0.1', unix_socket='/tmp/mysql.sock', user='root', passwd=None, db='mysql')
cur = conn.cursor()
cur.execute("SELECT Host,User FROM user")
for r in cur:
    print(r)
cur.close()
conn.close()

You should probably use pymysql – Pure Python MySQL client instead.
It works with Python 3.x, and doesn’t have any dependencies.

This pure Python MySQL client provides a DB-API to a MySQL database by talking directly to the server via the binary client/server protocol.

Example:

import pymysql
conn = pymysql.connect(host='127.0.0.1', unix_socket='/tmp/mysql.sock', user='root', passwd=None, db='mysql')
cur = conn.cursor()
cur.execute("SELECT Host,User FROM user")
for r in cur:
    print(r)
cur.close()
conn.close()

回答 2

我也尝试使用pymysql(在Win7 x64计算机上,Python 3.3),但运气不佳。我下载了.tar.gz,解压缩并运行“ setup.py install”,一切似乎都很好。直到我尝试连接到数据库并得到“ KeyError [56]”。我找不到任何地方记录的错误。

因此,我放弃了pymysql,而选择了Oracle MySQL连接器

它作为安装程序包提供,开箱即用。而且似乎也有据可查。

I also tried using pymysql (on my Win7 x64 machine, Python 3.3), without too much luck. I downloaded the .tar.gz, extract, ran “setup.py install”, and everything seemed fine. Until I tried connecting to a database, and got “KeyError [56]”. An error which I was unable to find documented anywhere.

So I gave up on pymysql, and I settled on the Oracle MySQL connector.

It comes as a setup package, and works out of the box. And it also seems decently documented.


回答 3

如果要先使用MySQLdb,则必须在Windows上键入cmd,在PC上安装pymysql

    pip install pymysql

然后在python shell中键入

    import pymysql
    pymysql.install_as_MySQLdb()
    import MySQLdb
    db = MySQLdb.connect("localhost" , "root" , "password")

这将建立连接。

if you want to use MySQLdb first you have to install pymysql on your pc by typing in cmd of windows

    pip install pymysql

then in python shell, type

    import pymysql
    pymysql.install_as_MySQLdb()
    import MySQLdb
    db = MySQLdb.connect("localhost" , "root" , "password")

this will establish the connection.


回答 4

未经测试,但在以下位置有一些可用的二进制文件:

非官方Windows二进制文件

Untested, but there are some binaries available at:

Unofficial Windows Binaries


回答 5

摘要

Mysqlclient是最佳选择(IMHO),因为它可以与Python 3+完美 协作,遵循预期的约定(与mysql连接器不同),使用对象名称mysqldb可以方便地移植现有软件,并且由Django用于python 3构建

mysqldb的二进制文件存在的地方有可用的存储库吗?

是。 mysqlclient允许您使用mysqldb函数。虽然,请记住,这不是 mysqldb 的直接端口,而是mysqlclient的构建

如何在Windows上的Python 3中连接到MySQL?

pip安装mysqlclient

#!/Python36/python
#Please change above path to suit your platform.  Am running it on Windows
import MySQLdb
db = MySQLdb.connect(user="my-username",passwd="my-password",host="localhost",db="my-databasename")
cursor = db.cursor()
cursor.execute("SELECT * from my-table-name")
data=cursor.fetchall()
for row in data :
    print (row)
db.close()

我找不到适用于Python 3的mysqldb。

mysqldb尚未移植

Summary

Mysqlclient is the best alternative(IMHO) because it works flawlessly with Python 3+, follows expected conventions (unlike mysql connector), uses the object name mysqldb which enables convenient porting of existing software and is used by Django for Python 3 builds

Is there a repository available where the binaries exist for mysqldb?

Yes. mysqlclient allows you to use mysqldb functions. Though, remember this is not a direct port by mysqldb, but a build by mysqlclient

How can I connect to MySQL in Python 3 on Windows?

pip install mysqlclient

Example

#!/Python36/python
#Please change above path to suit your platform.  Am running it on Windows
import MySQLdb
db = MySQLdb.connect(user="my-username",passwd="my-password",host="localhost",db="my-databasename")
cursor = db.cursor()
cursor.execute("SELECT * from my-table-name")
data=cursor.fetchall()
for row in data :
    print (row)
db.close()

I can’t find mysqldb for Python 3.

mysqldb has not been ported yet


回答 6

PyMySQL也提供类似MySQLDb的界面。您可以尝试进行初始化:

import pymysql
pymysql.install_as_MySQLdb()

github上还有一个用于python3的mysql-python端口。

https://github.com/davispuh/MySQL-for-Python-3

PyMySQL gives MySQLDb like interface as well. You could try in your initialization:

import pymysql
pymysql.install_as_MySQLdb()

Also there is a port of mysql-python on github for python3.

https://github.com/davispuh/MySQL-for-Python-3


回答 7

Oracle / MySQL提供了一个官方的纯Python DBAPI驱动程序:http ://dev.mysql.com/downloads/connector/python/

我在Python 3.3中使用了它,并发现它运行良好。还可以与SQLAlchemy一起使用。

另请参阅以下问题:登上Python 3火车是否还为时过早?

Oracle/MySQL provides an official, pure Python DBAPI driver: http://dev.mysql.com/downloads/connector/python/

I have used it with Python 3.3 and found it to work great. Also works with SQLAlchemy.

See also this question: Is it still too early to hop aboard the Python 3 train?


回答 8

在我的Mac OS X上,我尝试这样做:

之后,输入python3解释器并输入:

  1. 导入pymysql。如果没有错误,则表示安装正常。为了验证,编写一个脚本以这种形式连接到mysql:

  2. #一个用于MySQL连接的简单脚本import pymysql db = pymysql.connect(host =“ localhost”,user =“ root”,passwd =“* “,db =” biblioteca“)#当然,这是我的数据库的信息#关闭连接db.close()*

给它起一个名字(例如“ con.py”)并将其保存在桌面上。在终端中,键入“ cd desktop”,然后输入$ pythoncon.py。如果没有错误,则说明您已连接MySQL服务器。祝好运!

On my mac os maverick i try this:

After that, enter in the python3 interpreter and type:

  1. import pymysql. If there is no error your installation is ok. For verification write a script to connect to mysql with this form:

  2. # a simple script for MySQL connection import pymysql db = pymysql.connect(host=”localhost”, user=”root”, passwd=”*”, db=”biblioteca”) #Sure, this is information for my db # close the connection db.close ()*

Give it a name (“con.py” for example) and save it on desktop. In Terminal type “cd desktop” and then $python con.py If there is no error, you are connected with MySQL server. Good luck!


回答 9

CyMySQL https://github.com/nakagami/CyMySQL

我已经在Windows 7上安装了pip,使用python 3.3只是pip install cymysql

(您不需要赛顿)快速而无痛

CyMySQL https://github.com/nakagami/CyMySQL

I have installed pip on my windows 7, with python 3.3 just pip install cymysql

(you don’t need cython) quick and painless


回答 10

这并不能完全回答我最初的问题,但我认为让所有人知道我的工作和原因很重要。

由于网络上普遍存在2.7示例和模块,因此我选择继续使用python 2.7而不是python 3。

现在,我同时使用mysqldb和mysql.connector连接到Python 2.7中的MySQL。两者都很棒并且运作良好。我认为mysql.connector从长远来看最终会更好。

This does not fully answer my original question, but I think it is important to let everyone know what I did and why.

I chose to continue using python 2.7 instead of python 3 because of the prevalence of 2.7 examples and modules on the web in general.

I now use both mysqldb and mysql.connector to connect to MySQL in Python 2.7. Both are great and work well. I think mysql.connector is ultimately better long term however.


回答 11

我在树莓派上通过python3使用cymysql,我只需通过以下方式安装:sudo pip3 install cython sudo pip3 install cymysql在没有cython的情况下,但应使cymysql更快

到目前为止,它的工作原理很吸引人,与MySQLdb非常相似

I’m using cymysql with python3 on a raspberry pi I simply installed by: sudo pip3 install cython sudo pip3 install cymysql where cython is not necessary but should make cymysql faster

So far it works like a charm and very similar to MySQLdb


回答 12

这是一个有关如何使Python 3.7与Mysql一起使用的快速教程,
感谢所有得到我问题解答的人
-希望有一天能对您有所帮助。
————————————————– –
我的系统:
Windows版本:Pro 64位

要求..下载并安装这些第一…
1.下载XAMPP ..
https://www.apachefriends.org/download.html
2.下载的Python
https://www.python.org/downloads/windows/

– ————
//方法
————–
安装完成后,请先安装xampp-安装Python 3.7。
完成两者的安装后-重新启动Windows系统。
现在启动xampp并从控制面板启动mysql服务器。
通过打开CMD并在终端类型中确认版本

c:\>cd c:\xampp\mysql\bin

c:\xampp\mysql\bin>mysql -h localhost -v
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 10.1.21-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

这是检查MYSQL版本

c:\xampp\mysql\bin>python
Python 3.7.0b3 (v3.7.0b3:4e7efa9c6f, Mar 29 2018, 18:42:04) [MSC v.1913 64 bit (AMD64)] on win32

这是要检查Python版本,
既然都已确认,请在CMD中输入以下内容…

c:\xampp\mysql\bin>pip install pymysql

pymysql安装完成后。
在桌面上或其他任何地方创建一个名为“ testconn.py”的新文件以进行快速访问。
使用sublime或其他文本编辑器打开此文件,并将其放入其中。
切记更改设置以反映您的数据库。

#!/usr/bin/python
import pymysql
pymysql.install_as_MySQLdb() 

import MySQLdb
db = MySQLdb.connect(user="yourusernamehere",passwd="yourpasswordhere",host="yourhosthere",db="yourdatabasehere")
cursor = db.cursor()
cursor.execute("SELECT * from yourmysqltablehere")
data=cursor.fetchall()
for row in data :
    print (row)
db.close()

现在在您的CMD中-输入

c:\Desktop>testconn.py

就是这样…您现在已从python脚本完全连接到mysql …
享受…

This is a quick tutorial on how to get Python 3.7 working with Mysql
Thanks to all from who I got answers to my questions
– hope this helps somebody someday.
—————————————————-
My System:
Windows Version: Pro 64-bit

REQUIREMENTS.. download and install these first…
1. Download Xampp..
https://www.apachefriends.org/download.html
2. Download Python
https://www.python.org/downloads/windows/

————–
//METHOD
————–
Install xampp first after finished installing – install Python 3.7.
Once finished installing both – reboot your windows system.
Now start xampp and from the control panel – start the mysql server.
Confirm the versions by opening up CMD and in the terminal type

c:\>cd c:\xampp\mysql\bin

c:\xampp\mysql\bin>mysql -h localhost -v
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 2
Server version: 10.1.21-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others.

This is to check the MYSQL version

c:\xampp\mysql\bin>python
Python 3.7.0b3 (v3.7.0b3:4e7efa9c6f, Mar 29 2018, 18:42:04) [MSC v.1913 64 bit (AMD64)] on win32

This is to check the Python version
Now that both have been confirmed type the following into the CMD…

c:\xampp\mysql\bin>pip install pymysql

After the install of pymysql is completed.
create a new file called “testconn.py” on your desktop or whereever for quick access.
Open this file with sublime or another text editor and put this into it.
Remember to change the settings to reflect your database.

#!/usr/bin/python
import pymysql
pymysql.install_as_MySQLdb() 

import MySQLdb
db = MySQLdb.connect(user="yourusernamehere",passwd="yourpasswordhere",host="yourhosthere",db="yourdatabasehere")
cursor = db.cursor()
cursor.execute("SELECT * from yourmysqltablehere")
data=cursor.fetchall()
for row in data :
    print (row)
db.close()

Now in your CMD – type

c:\Desktop>testconn.py

And thats it… your now fully connected from a python script to mysql…
Enjoy…


回答 13

导入pymysql

打开数据库连接

db = pymysql.connect(“ localhost”,“ root”,“”,“装饰品”)

使用cursor()方法准备一个游标对象

cursor = db.cursor()

sql =“ SELECT * FROM项目”

cursor.execute(sql)

获取列表列表中的所有行。

结果=结果的cursor.fetchall():item_title = row [1]注释= row [2]打印(“项目标题为以下=%s,注释为以下=%s”%\(item_title,评论))

import pymysql

open database connection

db = pymysql.connect(“localhost”,”root”,””,”ornament”)

prepare a cursor object using cursor() method

cursor = db.cursor()

sql = “SELECT * FROM item”

cursor.execute(sql)

Fetch all the rows in a list of lists.

results = cursor.fetchall() for row in results: item_title = row[1] comment = row[2] print (“Title of items are the following = %s,Comments are the following = %s” % \ (item_title, comment))


TypeError:“ dict_keys”对象不支持索引

问题:TypeError:“ dict_keys”对象不支持索引

def shuffle(self, x, random=None, int=int):
    """x, random=random.random -> shuffle list x in place; return None.

    Optional arg random is a 0-argument function returning a random
    float in [0.0, 1.0); by default, the standard random.random.
    """

    randbelow = self._randbelow
    for i in reversed(range(1, len(x))):
        # pick an element in x[:i+1] with which to exchange x[i]
        j = randbelow(i+1) if random is None else int(random() * (i+1))
        x[i], x[j] = x[j], x[i]

当我运行该shuffle函数时,它会引发以下错误,这是为什么呢?

TypeError: 'dict_keys' object does not support indexing
def shuffle(self, x, random=None, int=int):
    """x, random=random.random -> shuffle list x in place; return None.

    Optional arg random is a 0-argument function returning a random
    float in [0.0, 1.0); by default, the standard random.random.
    """

    randbelow = self._randbelow
    for i in reversed(range(1, len(x))):
        # pick an element in x[:i+1] with which to exchange x[i]
        j = randbelow(i+1) if random is None else int(random() * (i+1))
        x[i], x[j] = x[j], x[i]

When I run the shuffle function it raises the following error, why is that?

TypeError: 'dict_keys' object does not support indexing

回答 0

显然,您正在传递d.keys()shuffle函数。可能是用python2.x编写的(d.keys()返回列表时)。使用python3.x,d.keys()返回一个dict_keys对象,其行为更像a而set不是alist。因此,无法对其进行索引。

解决方案是将list(d.keys())(或简单地list(d))传递给shuffle

Clearly you’re passing in d.keys() to your shuffle function. Probably this was written with python2.x (when d.keys() returned a list). With python3.x, d.keys() returns a dict_keys object which behaves a lot more like a set than a list. As such, it can’t be indexed.

The solution is to pass list(d.keys()) (or simply list(d)) to shuffle.


回答 1

您将把结果传递somedict.keys()给函数。在Python 3中,dict.keys它不返回列表,但是代表字典键视图的(类似于集合)的类似集合的对象不支持索引。

要解决此问题,请使用list(somedict.keys())来收集密钥并进行处理。

You’re passing the result of somedict.keys() to the function. In Python 3, dict.keys doesn’t return a list, but a set-like object that represents a view of the dictionary’s keys and (being set-like) doesn’t support indexing.

To fix the problem, use list(somedict.keys()) to collect the keys, and work with that.


回答 2

将迭代器转换为列表可能会产生成本。相反,要获得第一项,可以使用:

next(iter(keys))

或者,如果要遍历所有项目,则可以使用:

items = iter(keys)
while True:
    try:
        item = next(items)
    except StopIteration as e:
        pass # finish

Convert an iterable to a list may have a cost. Instead, to get the the first item, you can use:

next(iter(keys))

Or, if you want to iterate over all items, you can use:

items = iter(keys)
while True:
    try:
        item = next(items)
    except StopIteration as e:
        pass # finish

回答 3

为什么需要在已经存在的情况下实施改组?留在巨人的肩膀上。

import random

d1 = {0:'zero', 1:'one', 2:'two', 3:'three', 4:'four',
     5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'}

keys = list(d1)
random.shuffle(keys)

d2 = {}
for key in keys: d2[key] = d1[key]

print(d1)
print(d2)

Why you need to implement shuffle when it already exists? Stay on the shoulders of giants.

import random

d1 = {0:'zero', 1:'one', 2:'two', 3:'three', 4:'four',
     5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'}

keys = list(d1)
random.shuffle(keys)

d2 = {}
for key in keys: d2[key] = d1[key]

print(d1)
print(d2)

回答 4

在Python 2中,dict.keys()返回一个列表,而在Python 3中,它返回一个生成器。

您只能遍历其值,否则可能必须将其显式转换为列表,即将其传递给列表函数。

In Python 2 dict.keys() return a list, whereas in Python 3 it returns a generator.

You could only iterate over it’s values else you may have to explicitly convert it to a list i.e. pass it to a list function.


通过索引访问collections.OrderedDict中的项目

问题:通过索引访问collections.OrderedDict中的项目

可以说我有以下代码:

import collections
d = collections.OrderedDict()
d['foo'] = 'python'
d['bar'] = 'spam'

有没有一种方法可以以编号方式访问项目,例如:

d(0) #foo's Output
d(1) #bar's Output

Lets say I have the following code:

import collections
d = collections.OrderedDict()
d['foo'] = 'python'
d['bar'] = 'spam'

Is there a way I can access the items in a numbered manner, like:

d(0) #foo's Output
d(1) #bar's Output

回答 0

如果是OrderedDict(),则可以通过获取(key,value)对的元组的索引来轻松访问元素,如下所示

>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>> d.items()[0]
('foo', 'python')
>>> d.items()[1]
('bar', 'spam')

Python 3.X的注意事项

dict.items将返回一个可迭代的dict视图对象而不是一个列表。我们需要将调用包装到一个列表中,以使建立索引成为可能

>>> items = list(d.items())
>>> items
[('foo', 'python'), ('bar', 'spam')]
>>> items[0]
('foo', 'python')
>>> items[1]
('bar', 'spam')

If its an OrderedDict() you can easily access the elements by indexing by getting the tuples of (key,value) pairs as follows

>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>> d.items()[0]
('foo', 'python')
>>> d.items()[1]
('bar', 'spam')

Note for Python 3.X

dict.items would return an iterable dict view object rather than a list. We need to wrap the call onto a list in order to make the indexing possible

>>> items = list(d.items())
>>> items
[('foo', 'python'), ('bar', 'spam')]
>>> items[0]
('foo', 'python')
>>> items[1]
('bar', 'spam')

回答 1

您是否必须使用OrderedDict还是特别想要以快速位置索引以某种方式排序的类似地图的类型?如果是后者,则考虑使用Python多种排序的dict类型之一(根据键的排序顺序对键值对进行排序)。一些实现还支持快速索引。例如,为此目的,sortedcontainers项目具有SortedDict类型。

>>> from sortedcontainers import SortedDict
>>> sd = SortedDict()
>>> sd['foo'] = 'python'
>>> sd['bar'] = 'spam'
>>> print sd.iloc[0] # Note that 'bar' comes before 'foo' in sort order.
'bar'
>>> # If you want the value, then simple do a key lookup:
>>> print sd[sd.iloc[1]]
'python'

Do you have to use an OrderedDict or do you specifically want a map-like type that’s ordered in some way with fast positional indexing? If the latter, then consider one of Python’s many sorted dict types (which orders key-value pairs based on key sort order). Some implementations also support fast indexing. For example, the sortedcontainers project has a SortedDict type for just this purpose.

>>> from sortedcontainers import SortedDict
>>> sd = SortedDict()
>>> sd['foo'] = 'python'
>>> sd['bar'] = 'spam'
>>> print sd.iloc[0] # Note that 'bar' comes before 'foo' in sort order.
'bar'
>>> # If you want the value, then simple do a key lookup:
>>> print sd[sd.iloc[1]]
'python'

回答 2

如果您要在OrderedDict中创建第一个条目(或靠近它)而不创建列表,则是一种特殊情况。(此版本已更新为Python 3):

>>> from collections import OrderedDict
>>> 
>>> d = OrderedDict()
>>> d["foo"] = "one"
>>> d["bar"] = "two"
>>> d["baz"] = "three"
>>> next(iter(d.items()))
('foo', 'one')
>>> next(iter(d.values()))
'one'

(当您第一次说“ next()”时,它的意思实际上是“第一”。)

在我的非正式测试中,next(iter(d.items()))使用小OrderedDict仅比快一点items()[0]。使用10,000个条目的OrderedDict,next(iter(d.items()))比快200倍items()[0]

但是,如果您只保存items()列表一次,然后大量使用该列表,那可能会更快。或者,如果您反复{创建一个items()迭代器并将其逐步移动到所需位置},那可能会更慢。

Here is a special case if you want the first entry (or close to it) in an OrderedDict, without creating a list. (This has been updated to Python 3):

>>> from collections import OrderedDict
>>> 
>>> d = OrderedDict()
>>> d["foo"] = "one"
>>> d["bar"] = "two"
>>> d["baz"] = "three"
>>> next(iter(d.items()))
('foo', 'one')
>>> next(iter(d.values()))
'one'

(The first time you say “next()”, it really means “first.”)

In my informal test, next(iter(d.items())) with a small OrderedDict is only a tiny bit faster than items()[0]. With an OrderedDict of 10,000 entries, next(iter(d.items())) was about 200 times faster than items()[0].

BUT if you save the items() list once and then use the list a lot, that could be faster. Or if you repeatedly { create an items() iterator and step through it to to the position you want }, that could be slower.


回答 3

从包中使用IndexedOrderedDict会大大提高效率indexed

根据Niklas的评论,我对OrderedDictIndexedOrderedDict进行了基准测试,其中包含1000个条目。

In [1]: from numpy import *
In [2]: from indexed import IndexedOrderedDict
In [3]: id=IndexedOrderedDict(zip(arange(1000),random.random(1000)))
In [4]: timeit id.keys()[56]
1000000 loops, best of 3: 969 ns per loop

In [8]: from collections import OrderedDict
In [9]: od=OrderedDict(zip(arange(1000),random.random(1000)))
In [10]: timeit od.keys()[56]
10000 loops, best of 3: 104 µs per loop

在此特定情况下,在特定位置的索引元素中的IndexedOrderedDict快约100倍。

It is dramatically more efficient to use IndexedOrderedDict from the indexed package.

Following Niklas’s comment, I have done a benchmark on OrderedDict and IndexedOrderedDict with 1000 entries.

In [1]: from numpy import *
In [2]: from indexed import IndexedOrderedDict
In [3]: id=IndexedOrderedDict(zip(arange(1000),random.random(1000)))
In [4]: timeit id.keys()[56]
1000000 loops, best of 3: 969 ns per loop

In [8]: from collections import OrderedDict
In [9]: od=OrderedDict(zip(arange(1000),random.random(1000)))
In [10]: timeit od.keys()[56]
10000 loops, best of 3: 104 µs per loop

IndexedOrderedDict is ~100 times faster in indexing elements at specific position in this specific case.


回答 4

该社区Wiki尝试收集现有答案。

Python 2.7

在Python 2中,keys()values(),和items()函数OrderedDict的返回列表。使用values为例,最简单的方法是

d.values()[0]  # "python"
d.values()[1]  # "spam"

对于大集合,你只关心一个单一的指标,你能避免使用生成器版本创建的完整列表,iterkeysitervaluesiteritems

import itertools
next(itertools.islice(d.itervalues(), 0, 1))  # "python"
next(itertools.islice(d.itervalues(), 1, 2))  # "spam"

indexed.py包提供IndexedOrderedDict,这是专为这种使用情况下,将是最快的选项。

from indexed import IndexedOrderedDict
d = IndexedOrderedDict({'foo':'python','bar':'spam'})
d.values()[0]  # "python"
d.values()[1]  # "spam"

对于具有随机访问权限的大型词典,使用itervalues可能会更快:

$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 1000;   d = OrderedDict({i:i for i in range(size)})'  'i = randint(0, size-1); d.values()[i:i+1]'
1000 loops, best of 3: 259 usec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 10000;  d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
100 loops, best of 3: 2.3 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 100000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
10 loops, best of 3: 24.5 msec per loop

$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 1000;   d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
10000 loops, best of 3: 118 usec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 10000;  d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
1000 loops, best of 3: 1.26 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 100000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
100 loops, best of 3: 10.9 msec per loop

$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 1000;   d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.19 usec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 10000;  d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.24 usec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 100000; d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.61 usec per loop

+--------+-----------+----------------+---------+
|  size  | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
|   1000 | .259      | .118           | .00219  |
|  10000 | 2.3       | 1.26           | .00224  |
| 100000 | 24.5      | 10.9           | .00261  |
+--------+-----------+----------------+---------+

Python 3.6

Python 3具有相同的两个基本选项(列表vs生成器),但是默认情况下dict方法返回生成器。

清单方法:

list(d.values())[0]  # "python"
list(d.values())[1]  # "spam"

生成器方法:

import itertools
next(itertools.islice(d.values(), 0, 1))  # "python"
next(itertools.islice(d.values(), 1, 2))  # "spam"

Python 3字典比python 2快一个数量级,并且使用生成器的速度类似。

+--------+-----------+----------------+---------+
|  size  | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
|   1000 | .0316     | .0165          | .00262  |
|  10000 | .288      | .166           | .00294  |
| 100000 | 3.53      | 1.48           | .00332  |
+--------+-----------+----------------+---------+

This community wiki attempts to collect existing answers.

Python 2.7

In python 2, the keys(), values(), and items() functions of OrderedDict return lists. Using values as an example, the simplest way is

d.values()[0]  # "python"
d.values()[1]  # "spam"

For large collections where you only care about a single index, you can avoid creating the full list using the generator versions, iterkeys, itervalues and iteritems:

import itertools
next(itertools.islice(d.itervalues(), 0, 1))  # "python"
next(itertools.islice(d.itervalues(), 1, 2))  # "spam"

The indexed.py package provides IndexedOrderedDict, which is designed for this use case and will be the fastest option.

from indexed import IndexedOrderedDict
d = IndexedOrderedDict({'foo':'python','bar':'spam'})
d.values()[0]  # "python"
d.values()[1]  # "spam"

Using itervalues can be considerably faster for large dictionaries with random access:

$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 1000;   d = OrderedDict({i:i for i in range(size)})'  'i = randint(0, size-1); d.values()[i:i+1]'
1000 loops, best of 3: 259 usec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 10000;  d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
100 loops, best of 3: 2.3 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 100000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i:i+1]'
10 loops, best of 3: 24.5 msec per loop

$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 1000;   d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
10000 loops, best of 3: 118 usec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 10000;  d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
1000 loops, best of 3: 1.26 msec per loop
$ python2 -m timeit -s 'from collections import OrderedDict; from random import randint; size = 100000; d = OrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); next(itertools.islice(d.itervalues(), i, i+1))'
100 loops, best of 3: 10.9 msec per loop

$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 1000;   d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.19 usec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 10000;  d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.24 usec per loop
$ python2 -m timeit -s 'from indexed import IndexedOrderedDict; from random import randint; size = 100000; d = IndexedOrderedDict({i:i for i in range(size)})' 'i = randint(0, size-1); d.values()[i]'
100000 loops, best of 3: 2.61 usec per loop

+--------+-----------+----------------+---------+
|  size  | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
|   1000 | .259      | .118           | .00219  |
|  10000 | 2.3       | 1.26           | .00224  |
| 100000 | 24.5      | 10.9           | .00261  |
+--------+-----------+----------------+---------+

Python 3.6

Python 3 has the same two basic options (list vs generator), but the dict methods return generators by default.

List method:

list(d.values())[0]  # "python"
list(d.values())[1]  # "spam"

Generator method:

import itertools
next(itertools.islice(d.values(), 0, 1))  # "python"
next(itertools.islice(d.values(), 1, 2))  # "spam"

Python 3 dictionaries are an order of magnitude faster than python 2 and have similar speedups for using generators.

+--------+-----------+----------------+---------+
|  size  | list (ms) | generator (ms) | indexed |
+--------+-----------+----------------+---------+
|   1000 | .0316     | .0165          | .00262  |
|  10000 | .288      | .166           | .00294  |
| 100000 | 3.53      | 1.48           | .00332  |
+--------+-----------+----------------+---------+

回答 5

这是一个新时代,Python 3.6.1词典现在可以保留其顺序。这些语义不明确,因为这需要BDFL批准。但是雷蒙德·海廷格(Raymond Hettinger)是下一个最好的东西(而且更有趣),他提出了一个非常有力的理由,那就是字典将在很长一段时间内被订购。

因此,现在很容易创建字典的切片:

test_dict = {
                'first':  1,
                'second': 2,
                'third':  3,
                'fourth': 4
            }

list(test_dict.items())[:2]

注意:现在,字典插入顺序保留在Python 3.7中正式的

It’s a new era and with Python 3.6.1 dictionaries now retain their order. These semantics aren’t explicit because that would require BDFL approval. But Raymond Hettinger is the next best thing (and funnier) and he makes a pretty strong case that dictionaries will be ordered for a very long time.

So now it’s easy to create slices of a dictionary:

test_dict = {
                'first':  1,
                'second': 2,
                'third':  3,
                'fourth': 4
            }

list(test_dict.items())[:2]

Note: Dictonary insertion-order preservation is now official in Python 3.7.


回答 6

对于OrderedDict(),您可以通过按以下方式获取(键,值)对的元组或通过使用’.values()’进行索引来访问元素。

>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>>d.values()
odict_values(['python','spam'])
>>>list(d.values())
['python','spam']

for OrderedDict() you can access the elements by indexing by getting the tuples of (key,value) pairs as follows or using ‘.values()’

>>> import collections
>>> d = collections.OrderedDict()
>>> d['foo'] = 'python'
>>> d['bar'] = 'spam'
>>> d.items()
[('foo', 'python'), ('bar', 'spam')]
>>>d.values()
odict_values(['python','spam'])
>>>list(d.values())
['python','spam']

TypeError:参数有多个值

问题:TypeError:参数有多个值

我读了与该错误有关的其他线程,似乎我的问题与到目前为止所读的所有帖子都有一个有趣的明显区别,即,到目前为止,所有其他帖子在创建一个用户方面都存在错误类或内置系统资源。调用函数时遇到此问题,我无法弄清楚它的用途。有任何想法吗?

BOX_LENGTH = 100
turtle.speed(0)
fill = 0
for i in range(8):
    fill += 1
    if fill % 2 == 0:
        Horizontol_drawbox(BOX_LENGTH, fillBox = False)
    else:
        Horizontol_drawbox(BOX_LENGTH, fillBox = True)

    for i in range(8):
        fill += 1
        if fill % 2 == 0:
            Vertical_drawbox(BOX_LENGTH,fillBox = False)
        else:
            Vertical_drawbox(BOX_LENGTH,fillBox = True)

错误信息:

    Horizontol_drawbox(BOX_LENGTH, fillBox = True)
TypeError: Horizontol_drawbox() got multiple values for argument 'fillBox'

I read the other threads that had to do with this error and it seems that my problem has an interesting distinct difference than all the posts I read so far, namely, all the other posts so far have the error in regards to either a user created class or a builtin system resource. I am experiencing this problem when calling a function, I can’t figure out what it could be for. Any ideas?

BOX_LENGTH = 100
turtle.speed(0)
fill = 0
for i in range(8):
    fill += 1
    if fill % 2 == 0:
        Horizontol_drawbox(BOX_LENGTH, fillBox = False)
    else:
        Horizontol_drawbox(BOX_LENGTH, fillBox = True)

    for i in range(8):
        fill += 1
        if fill % 2 == 0:
            Vertical_drawbox(BOX_LENGTH,fillBox = False)
        else:
            Vertical_drawbox(BOX_LENGTH,fillBox = True)

Error message:

    Horizontol_drawbox(BOX_LENGTH, fillBox = True)
TypeError: Horizontol_drawbox() got multiple values for argument 'fillBox'

回答 0

当指定关键字参数覆盖位置参数时,会发生这种情况。例如,让我们想象一个绘制彩色框的函数。该函数选择要使用的颜色,并将框的图形委托给另一个函数,从而中继所有其他参数。

def color_box(color, *args, **kwargs):
    painter.select_color(color)
    painter.draw_box(*args, **kwargs)

然后打电话

color_box("blellow", color="green", height=20, width=30)

将失败,因为将两个值分配给了color"blellow"作为position和"green"as关键字。(painter.draw_box应该接受heightwidth参数)。

在示例中很容易看到这一点,但是当然,如​​果在调用时混淆了参数,则调试起来可能并不容易:

# misplaced height and width
color_box(20, 30, color="green")

在这里,color被分配20,然后args=[30]color被分配"green"

This happens when a keyword argument is specified that overwrites a positional argument. For example, let’s imagine a function that draws a colored box. The function selects the color to be used and delegates the drawing of the box to another function, relaying all extra arguments.

def color_box(color, *args, **kwargs):
    painter.select_color(color)
    painter.draw_box(*args, **kwargs)

Then the call

color_box("blellow", color="green", height=20, width=30)

will fail because two values are assigned to color: "blellow" as positional and "green" as keyword. (painter.draw_box is supposed to accept the height and width arguments).

This is easy to see in the example, but of course if one mixes up the arguments at call, it may not be easy to debug:

# misplaced height and width
color_box(20, 30, color="green")

Here, color is assigned 20, then args=[30] and color is again assigned "green".


回答 1

我遇到的问题确实很容易解决,但花了我一段时间才看穿。

我已经将声明复制到我使用它的地方,并且在此处留下了“自我”的论点,但是我花了很长时间才意识到这一点。

我有

self.myFunction(self, a, b, c='123')

但这应该是

self.myFunction(a, b, c='123')

I had the same problem that is really easy to make, but took me a while to see through.

I had copied the declaration to where I was using it and had left the ‘self’ argument there, but it took me ages to realise that.

I had

self.myFunction(self, a, b, c='123')

but it should have been

self.myFunction(a, b, c='123')

回答 2

如果您忘记了self类方法中的声明,也会发生这种情况。

例:

class Example():
    def is_overlapping(x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

未能通过以下方式调用它self.is_overlapping(x1=2, x2=4, y1=3, y2=5)

{TypeError} is_overlapping()为参数“ x1”获得了多个值

作品

class Example():
    def is_overlapping(self, x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

This also happens if you forget selfdeclaration inside class methods.

Example:

class Example():
    def is_overlapping(x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

Fails calling it like self.is_overlapping(x1=2, x2=4, y1=3, y2=5) with:

{TypeError} is_overlapping() got multiple values for argument ‘x1’

WORKS:

class Example():
    def is_overlapping(self, x1, x2, y1, y2):
        # Thanks to https://stackoverflow.com/a/12888920/940592
        return max(x1, y1) <= min(x2, y2)

回答 3

我的问题类似于Q —十的问题,但是在我的情况下,我忘记了为类函数提供self参数:

class A:
    def fn(a, b, c=True):
        pass

应该成为

class A:
    def fn(self, a, b, c=True):
        pass

当以如下方式调用类方法时,很难看到这种错误的实现:

a_obj = A()
a.fn(a_val, b_val, c=False)

这将产生一个TypeError: got multiple values for argument。希望这里的其余答案很清楚,任何人都可以快速理解并解决错误。如果没有,希望这个答案对您有帮助!

My issue was similar to Q—ten’s, but in my case it was that I had forgotten to provide the self argument to a class function:

class A:
    def fn(a, b, c=True):
        pass

Should become

class A:
    def fn(self, a, b, c=True):
        pass

This faulty implementation is hard to see when calling the class method as:

a_obj = A()
a.fn(a_val, b_val, c=False)

Which will yield a TypeError: got multiple values for argument. Hopefully, the rest of the answers here are clear enough for anyone to be able to quickly understand and fix the error. If not, hope this answer helps you!


回答 4

简而言之,您不能执行以下操作:

class C(object):
    def x(self, y, **kwargs):
        # Which y to use, kwargs or declaration? 
        pass

c = C()
y = "Arbitrary value"
kwargs["y"] = "Arbitrary value"
c.x(y, **kwargs) # FAILS

因为您将变量y两次传递给函数:一次作为kwargs,一次作为函数声明。

Simply put you can’t do the following:

class C(object):
    def x(self, y, **kwargs):
        # Which y to use, kwargs or declaration? 
        pass

c = C()
y = "Arbitrary value"
kwargs["y"] = "Arbitrary value"
c.x(y, **kwargs) # FAILS

Because you pass the variable ‘y’ into the function twice: once as kwargs and once as function declaration.


回答 5

我被带到这里的原因是到目前为止答案中没有明确提及的原因,因此可以避免其他麻烦:

如果函数参数已更改顺序,也会发生错误-出于与接受的答案相同的原因:位置参数与关键字参数发生冲突。

就我而言,这是因为Pandas set_axis函数的参数顺序在0.20和0.22之间变化:

0.20: DataFrame.set_axis(axis, labels)
0.22: DataFrame.set_axis(labels, axis=0, inplace=None)

使用set_axis的常见示例会导致此令人困惑的错误,因为在您调用时:

df.set_axis(['a', 'b', 'c'], axis=1)

将0.22之前的['a', 'b', 'c']值分配给axis,因为它是第一个参数,然后位置参数提供“多个值”。

I was brought here for a reason not explicitly mentioned in the answers so far, so to save others the trouble:

The error also occurs if the function arguments have changed order – for the same reason as in the accepted answer: the positional arguments clash with the keyword arguments.

In my case it was because the argument order of the Pandas set_axis function changed between 0.20 and 0.22:

0.20: DataFrame.set_axis(axis, labels)
0.22: DataFrame.set_axis(labels, axis=0, inplace=None)

Using the commonly found examples for set_axis results in this confusing error, since when you call:

df.set_axis(['a', 'b', 'c'], axis=1)

prior to 0.22, ['a', 'b', 'c'] is assigned to axis because it’s the first argument, and then the positional argument provides “multiple values”.


Python中except:和except Exception之间的区别,例如e:

问题:Python中except:和except Exception之间的区别,例如e:

以下两个代码段都执行相同的操作。他们捕获每个异常并执行except:块中的代码

片段1-

try:
    #some code that may throw an exception
except:
    #exception handling code

摘要2-

try:
    #some code that may throw an exception
except Exception as e:
    #exception handling code

两种结构到底有什么区别?

Both the following snippets of code do the same thing. They catch every exception and execute the code in the except: block

Snippet 1 –

try:
    #some code that may throw an exception
except:
    #exception handling code

Snippet 2 –

try:
    #some code that may throw an exception
except Exception as e:
    #exception handling code

What is exactly the difference in both the constructs?


回答 0

在第二个中,您可以访问异常对象的属性:

>>> def catch():
...     try:
...         asd()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
global name 'asd' is not defined ("global name 'asd' is not defined",)

但是它不会捕获BaseException或系统退出异常SystemExitKeyboardInterrupt并且GeneratorExit

>>> def catch():
...     try:
...         raise BaseException()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in catch
BaseException

除了一个裸露的:

>>> def catch():
...     try:
...         raise BaseException()
...     except:
...         pass
... 
>>> catch()
>>> 

有关更多信息,请参阅文档的“ 内置异常”部分和本教程的“ 错误与异常”部分。

In the second you can access the attributes of the exception object:

>>> def catch():
...     try:
...         asd()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
global name 'asd' is not defined ("global name 'asd' is not defined",)

But it doesn’t catch BaseException or the system-exiting exceptions SystemExit, KeyboardInterrupt and GeneratorExit:

>>> def catch():
...     try:
...         raise BaseException()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in catch
BaseException

Which a bare except does:

>>> def catch():
...     try:
...         raise BaseException()
...     except:
...         pass
... 
>>> catch()
>>> 

See the Built-in Exceptions section of the docs and the Errors and Exceptions section of the tutorial for more info.


回答 1

except:

接受所有exceptions,而

except Exception as e:

只接受您打算捕获的异常。

这是您无意中发现的一个示例:

>>> try:
...     input()
... except:
...     pass
... 
>>> try:
...     input()
... except Exception as e:
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

第一个沉默了KeyboardInterrupt

快速清单:

issubclass(BaseException, BaseException)
#>>> True
issubclass(BaseException, Exception)
#>>> False


issubclass(KeyboardInterrupt, BaseException)
#>>> True
issubclass(KeyboardInterrupt, Exception)
#>>> False


issubclass(SystemExit, BaseException)
#>>> True
issubclass(SystemExit, Exception)
#>>> False

如果您想抓住其中任何一个,最好去做

except BaseException:

指出您知道自己在做什么。


所有异常都源于BaseException,您打算每天捕获的异常(那些将抛出程序员的异常)也继承自Exception

except:

accepts all exceptions, whereas

except Exception as e:

only accepts exceptions that you’re meant to catch.

Here’s an example of one that you’re not meant to catch:

>>> try:
...     input()
... except:
...     pass
... 
>>> try:
...     input()
... except Exception as e:
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

The first one silenced the KeyboardInterrupt!

Here’s a quick list:

issubclass(BaseException, BaseException)
#>>> True
issubclass(BaseException, Exception)
#>>> False


issubclass(KeyboardInterrupt, BaseException)
#>>> True
issubclass(KeyboardInterrupt, Exception)
#>>> False


issubclass(SystemExit, BaseException)
#>>> True
issubclass(SystemExit, Exception)
#>>> False

If you want to catch any of those, it’s best to do

except BaseException:

to point out that you know what you’re doing.


All exceptions stem from BaseException, and those you’re meant to catch day-to-day (those that’ll be thrown for the programmer) inherit too from Exception.


回答 2

除某些exceptions外,还有其他区别,例如KeyboardInterrupt。

阅读PEP8

仅有的except:子句将捕获SystemExit和KeyboardInterrupt异常,这使得使用Control-C中断程序更加困难,并且可以掩盖其他问题。如果要捕获所有表示程序错误的异常,请使用Exception:除外(裸除等效于BaseException:除外)。

There are differences with some exceptions, e.g. KeyboardInterrupt.

Reading PEP8:

A bare except: clause will catch SystemExit and KeyboardInterrupt exceptions, making it harder to interrupt a program with Control-C, and can disguise other problems. If you want to catch all exceptions that signal program errors, use except Exception: (bare except is equivalent to except BaseException:).


回答 3

使用第二种形式会在块范围内为您提供一个变量(根据as示例中的子句命名e),并except绑定了异常对象,因此您可以在异常中使用信息(类型,消息,堆栈跟踪等)来在更特别的庄园中处理exceptions情况。

Using the second form gives you a variable (named based upon the as clause, in your example e) in the except block scope with the exception object bound to it so you can use the infomration in the exception (type, message, stack trace, etc) to handle the exception in a more specially tailored manor.


回答 4

另一种看待这一点的方式。查看异常的详细信息:

In [49]: try: 
    ...:     open('file.DNE.txt') 
    ...: except Exception as  e: 
    ...:     print(dir(e)) 
    ...:                                                                                                                                    
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'characters_written', 'errno', 'filename', 'filename2', 'strerror', 'with_traceback']

使用“ as e”语法可以访问许多“事物”。

该代码仅用于显示该实例的详细信息。

Another way to look at this. Check out of the details of the exception:

In [49]: try: 
    ...:     open('file.DNE.txt') 
    ...: except Exception as  e: 
    ...:     print(dir(e)) 
    ...:                                                                                                                                    
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'characters_written', 'errno', 'filename', 'filename2', 'strerror', 'with_traceback']

There are lots of “things” to access using the ‘as e’ syntax.

This code was solely meant to show the details of this instance.


如何用熊猫DataFrame中的先前值替换NaN?

问题:如何用熊猫DataFrame中的先前值替换NaN?

假设我有一个带有NaNs 的DataFrame :

>>> import pandas as pd
>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df
    0   1   2
0   1   2   3
1   4 NaN NaN
2 NaN NaN   9

我需要做的是用上面同一列中NaN的第一个非NaN值替换每个值。假设第一行永远不会包含NaN。因此,对于前面的示例,结果将是

   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

我可以遍历整个DataFrame的逐列,逐元素并直接设置值,但是是否有一种简单的方法(最佳无循环)来实现呢?

Suppose I have a DataFrame with some NaNs:

>>> import pandas as pd
>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df
    0   1   2
0   1   2   3
1   4 NaN NaN
2 NaN NaN   9

What I need to do is replace every NaN with the first non-NaN value in the same column above it. It is assumed that the first row will never contain a NaN. So for the previous example the result would be

   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

I can just loop through the whole DataFrame column-by-column, element-by-element and set the values directly, but is there an easy (optimally a loop-free) way of achieving this?


回答 0

您可以fillna在DataFrame上使用该方法,并将该方法指定为ffill(正向填充):

>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df.fillna(method='ffill')
   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

这个方法

将上一个有效观察结果传播到下一个有效观察结果

相反,还有一个 bfill方法。

此方法不会就地修改DataFrame-您需要将返回的DataFrame重新绑定到变量,或者指定inplace=True

df.fillna(method='ffill', inplace=True)

You could use the fillna method on the DataFrame and specify the method as ffill (forward fill):

>>> df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
>>> df.fillna(method='ffill')
   0  1  2
0  1  2  3
1  4  2  3
2  4  2  9

This method…

propagate[s] last valid observation forward to next valid

To go the opposite way, there’s also a bfill method.

This method doesn’t modify the DataFrame inplace – you’ll need to rebind the returned DataFrame to a variable or else specify inplace=True:

df.fillna(method='ffill', inplace=True)

回答 1

公认的答案是完美的。我遇到了一个相关但略有不同的情况,我必须向前填写,但只能在小组中填写。如果有人有相同的需求,请知道fillna可用于DataFrameGroupBy对象。

>>> example = pd.DataFrame({'number':[0,1,2,nan,4,nan,6,7,8,9],'name':list('aaabbbcccc')})
>>> example
  name  number
0    a     0.0
1    a     1.0
2    a     2.0
3    b     NaN
4    b     4.0
5    b     NaN
6    c     6.0
7    c     7.0
8    c     8.0
9    c     9.0
>>> example.groupby('name')['number'].fillna(method='ffill') # fill in row 5 but not row 3
0    0.0
1    1.0
2    2.0
3    NaN
4    4.0
5    4.0
6    6.0
7    7.0
8    8.0
9    9.0
Name: number, dtype: float64

The accepted answer is perfect. I had a related but slightly different situation where I had to fill in forward but only within groups. In case someone has the same need, know that fillna works on a DataFrameGroupBy object.

>>> example = pd.DataFrame({'number':[0,1,2,nan,4,nan,6,7,8,9],'name':list('aaabbbcccc')})
>>> example
  name  number
0    a     0.0
1    a     1.0
2    a     2.0
3    b     NaN
4    b     4.0
5    b     NaN
6    c     6.0
7    c     7.0
8    c     8.0
9    c     9.0
>>> example.groupby('name')['number'].fillna(method='ffill') # fill in row 5 but not row 3
0    0.0
1    1.0
2    2.0
3    NaN
4    4.0
5    4.0
6    6.0
7    7.0
8    8.0
9    9.0
Name: number, dtype: float64

回答 2

您可以使用pandas.DataFrame.fillnamethod='ffill'选项。'ffill'代表“向前填充”,并将向前传播最后一个有效观察值。替代方法是'bfill'相同的方法,但倒退。

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
df = df.fillna(method='ffill')

print(df)
#   0  1  2
#0  1  2  3
#1  4  2  3
#2  4  2  9

为此,还有一个直接的同义词功能pandas.DataFrame.ffill,可以简化操作。

You can use pandas.DataFrame.fillna with the method='ffill' option. 'ffill' stands for ‘forward fill’ and will propagate last valid observation forward. The alternative is 'bfill' which works the same way, but backwards.

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])
df = df.fillna(method='ffill')

print(df)
#   0  1  2
#0  1  2  3
#1  4  2  3
#2  4  2  9

There is also a direct synonym function for this, pandas.DataFrame.ffill, to make things simpler.


回答 3

我在尝试此解决方案时注意到的一件事是,如果您在数组的开头或结尾处都没有N / A,则填充和填充将无法正常工作。你们两个都需要。

In [224]: df = pd.DataFrame([None, 1, 2, 3, None, 4, 5, 6, None])

In [225]: df.ffill()
Out[225]:
     0
0  NaN
1  1.0
...
7  6.0
8  6.0

In [226]: df.bfill()
Out[226]:
     0
0  1.0
1  1.0
...
7  6.0
8  NaN

In [227]: df.bfill().ffill()
Out[227]:
     0
0  1.0
1  1.0
...
7  6.0
8  6.0

One thing that I noticed when trying this solution is that if you have N/A at the start or the end of the array, ffill and bfill don’t quite work. You need both.

In [224]: df = pd.DataFrame([None, 1, 2, 3, None, 4, 5, 6, None])

In [225]: df.ffill()
Out[225]:
     0
0  NaN
1  1.0
...
7  6.0
8  6.0

In [226]: df.bfill()
Out[226]:
     0
0  1.0
1  1.0
...
7  6.0
8  NaN

In [227]: df.bfill().ffill()
Out[227]:
     0
0  1.0
1  1.0
...
7  6.0
8  6.0

回答 4

ffill 现在有自己的方法 pd.DataFrame.ffill

df.ffill()

     0    1    2
0  1.0  2.0  3.0
1  4.0  2.0  3.0
2  4.0  2.0  9.0

ffill now has it’s own method pd.DataFrame.ffill

df.ffill()

     0    1    2
0  1.0  2.0  3.0
1  4.0  2.0  3.0
2  4.0  2.0  9.0

回答 5

仅一列版本

  • 最后一个有效值填充NAN
df[column_name].fillna(method='ffill', inplace=True)
  • 下一个有效值填充NAN
df[column_name].fillna(method='backfill', inplace=True)

Only one column version

  • Fill NAN with last valid value
df[column_name].fillna(method='ffill', inplace=True)
  • Fill NAN with next valid value
df[column_name].fillna(method='backfill', inplace=True)

回答 6

只是同意ffillmethod,但是一个额外的信息是您可以使用关键字arguments限制正向填充limit

>>> import pandas as pd    
>>> df = pd.DataFrame([[1, 2, 3], [None, None, 6], [None, None, 9]])

>>> df
     0    1   2
0  1.0  2.0   3
1  NaN  NaN   6
2  NaN  NaN   9

>>> df[1].fillna(method='ffill', inplace=True)
>>> df
     0    1    2
0  1.0  2.0    3
1  NaN  2.0    6
2  NaN  2.0    9

现在带有limit关键字参数

>>> df[0].fillna(method='ffill', limit=1, inplace=True)

>>> df
     0    1  2
0  1.0  2.0  3
1  1.0  2.0  6
2  NaN  2.0  9

Just agreeing with ffill method, but one extra info is that you can limit the forward fill with keyword argument limit.

>>> import pandas as pd    
>>> df = pd.DataFrame([[1, 2, 3], [None, None, 6], [None, None, 9]])

>>> df
     0    1   2
0  1.0  2.0   3
1  NaN  NaN   6
2  NaN  NaN   9

>>> df[1].fillna(method='ffill', inplace=True)
>>> df
     0    1    2
0  1.0  2.0    3
1  NaN  2.0    6
2  NaN  2.0    9

Now with limit keyword argument

>>> df[0].fillna(method='ffill', limit=1, inplace=True)

>>> df
     0    1  2
0  1.0  2.0  3
1  1.0  2.0  6
2  NaN  2.0  9

回答 7

就我而言,我们有来自不同设备的时间序列,但是某些设备在一段时间内无法发送任何值。因此,我们应该为每个设备和时间段创建NA值,然后再执行fillna。

df = pd.DataFrame([["device1", 1, 'first val of device1'], ["device2", 2, 'first val of device2'], ["device3", 3, 'first val of device3']])
df.pivot(index=1, columns=0, values=2).fillna(method='ffill').unstack().reset_index(name='value')

结果:

        0   1   value
0   device1     1   first val of device1
1   device1     2   first val of device1
2   device1     3   first val of device1
3   device2     1   None
4   device2     2   first val of device2
5   device2     3   first val of device2
6   device3     1   None
7   device3     2   None
8   device3     3   first val of device3

In my case, we have time series from different devices but some devices could not send any value during some period. So we should create NA values for every device and time period and after that do fillna.

df = pd.DataFrame([["device1", 1, 'first val of device1'], ["device2", 2, 'first val of device2'], ["device3", 3, 'first val of device3']])
df.pivot(index=1, columns=0, values=2).fillna(method='ffill').unstack().reset_index(name='value')

Result:

        0   1   value
0   device1     1   first val of device1
1   device1     2   first val of device1
2   device1     3   first val of device1
3   device2     1   None
4   device2     2   first val of device2
5   device2     3   first val of device2
6   device3     1   None
7   device3     2   None
8   device3     3   first val of device3

回答 8

您可以fillna用来删除或替换NaN值。

NaN 移除

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])

df.fillna(method='ffill')
     0    1    2
0  1.0  2.0  3.0
1  4.0  2.0  3.0
2  4.0  2.0  9.0

NaN 替换

df.fillna(0) # 0 means What Value you want to replace 
     0    1    2
0  1.0  2.0  3.0
1  4.0  0.0  0.0
2  0.0  0.0  9.0

参考pandas.DataFrame.fillna

You can use fillna to remove or replace NaN values.

NaN Remove

import pandas as pd

df = pd.DataFrame([[1, 2, 3], [4, None, None], [None, None, 9]])

df.fillna(method='ffill')
     0    1    2
0  1.0  2.0  3.0
1  4.0  2.0  3.0
2  4.0  2.0  9.0

NaN Replace

df.fillna(0) # 0 means What Value you want to replace 
     0    1    2
0  1.0  2.0  3.0
1  4.0  0.0  0.0
2  0.0  0.0  9.0

Reference pandas.DataFrame.fillna


Python 3中是否有一个“ foreach”功能?

问题:Python 3中是否有一个“ foreach”功能?

当我遇到这种情况时,我可以使用javascript做到这一点,我一直认为如果有一个foreach功能会很方便。通过foreach,我的意思是下面描述的功能:

def foreach(fn,iterable):
    for x in iterable:
        fn(x)

他们只是在每个元素上执行它,而不产生或返回任何东西,我认为它应该是一个内置函数,并且应该比使用纯Python编写它要快,但我没有在列表中找到它,或者它只是叫另一个名字?还是我在这里想念一些要点?

也许我弄错了,导致在Python中调用函数的成本很高,绝对不是该示例的好习惯。该函数应该在其主体看起来像下面这样的循环中进行循环,而不是在out循环中进行下面的循环,这在许多python的代码建议中已经提到:

def fn(*args):
    for x in args:
       dosomething

但基于以下两个事实,我认为foreach仍然受欢迎:

  1. 通常情况下,人们只是不在乎性能
  2. 有时,API不接受可迭代对象,因此您无法重写其源代码。

When I meet the situation I can do it in javascript, I always think if there’s an foreach function it would be convenience. By foreach I mean the function which is described below:

def foreach(fn,iterable):
    for x in iterable:
        fn(x)

they just do it on every element and didn’t yield or return something,i think it should be a built-in function and should be more faster than writing it with pure Python, but I didn’t found it on the list,or it just called another name?or I just miss some points here?

Maybe I got wrong, cause calling an function in Python cost high, definitely not a good practice for the example. Rather than an out loop, the function should do the loop in side its body looks like this below which already mentioned in many python’s code suggestions:

def fn(*args):
    for x in args:
       dosomething

but I thought foreach is still welcome base on the two facts:

  1. In normal cases, people just don’t care about the performance
  2. Sometime the API didn’t accept iterable object and you can’t rewrite its source.

回答 0

我所见过的每次出现的“ foreach”(PHP,C#等)与python的“ for”语句基本相同。

这些大致相同:

// PHP:
foreach ($array as $val) {
    print($val);
}

// C#
foreach (String val in array) {
    console.writeline(val);
}

// Python
for val in array:
    print(val)

因此,是的,python中有一个“ foreach”。它称为“ for”。

您要描述的是“数组映射”功能。这可以通过python中的列表理解来完成:

names = ['tom', 'john', 'simon']

namesCapitalized = [capitalize(n) for n in names]

Every occurence of “foreach” I’ve seen (PHP, C#, …) does basically the same as pythons “for” statement.

These are more or less equivalent:

// PHP:
foreach ($array as $val) {
    print($val);
}

// C#
foreach (String val in array) {
    console.writeline(val);
}

// Python
for val in array:
    print(val)

So, yes, there is a “foreach” in python. It’s called “for”.

What you’re describing is an “array map” function. This could be done with list comprehensions in python:

names = ['tom', 'john', 'simon']

namesCapitalized = [capitalize(n) for n in names]

回答 1

Python没有一个foreach说法本身。它具有for内置在语言中的循环。

for element in iterable:
    operate(element)

如果确实需要,可以定义自己的foreach函数:

def foreach(function, iterable):
    for element in iterable:
        function(element)

附带说明一下,for element in iterable语法来自ABC编程语言,这是Python的影响之一。

Python doesn’t have a foreach statement per se. It has for loops built into the language.

for element in iterable:
    operate(element)

If you really wanted to, you could define your own foreach function:

def foreach(function, iterable):
    for element in iterable:
        function(element)

As a side note the for element in iterable syntax comes from the ABC programming language, one of Python’s influences.


回答 2

其他例子:

Python Foreach循环:

array = ['a', 'b']
for value in array:
    print(value)
    # a
    # b

Python For循环:

array = ['a', 'b']
for index in range(len(array)):
    print("index: %s | value: %s" % (index, array[index]))
    # index: 0 | value: a
    # index: 1 | value: b

Other examples:

Python Foreach Loop:

array = ['a', 'b']
for value in array:
    print(value)
    # a
    # b

Python For Loop:

array = ['a', 'b']
for index in range(len(array)):
    print("index: %s | value: %s" % (index, array[index]))
    # index: 0 | value: a
    # index: 1 | value: b

回答 3

map 可以用于问题中提到的情况。

例如

map(len, ['abcd','abc', 'a']) # 4 3 1

对于带有多个参数的函数,可以给映射提供更多参数:

map(pow, [2, 3], [4,2]) # 16 9

它在python 2.x中返回一个列表,在python 3中返回一个迭代器

如果您的函数接受多个参数,并且这些参数已经是元组形式(或者自python 2.6起是可迭代的),则可以使用itertools.starmap。(其语法与您要查找的语法非常相似)。它返回一个迭代器。

例如

for num in starmap(pow, [(2,3), (3,2)]):
    print(num)

给我们8和9

map can be used for the situation mentioned in the question.

E.g.

map(len, ['abcd','abc', 'a']) # 4 3 1

For functions that take multiple arguments, more arguments can be given to map:

map(pow, [2, 3], [4,2]) # 16 9

It returns a list in python 2.x and an iterator in python 3

In case your function takes multiple arguments and the arguments are already in the form of tuples (or any iterable since python 2.6) you can use itertools.starmap. (which has a very similar syntax to what you were looking for). It returns an iterator.

E.g.

for num in starmap(pow, [(2,3), (3,2)]):
    print(num)

gives us 8 and 9


回答 4

这在python 3中做了foreach

test = [0,1,2,3,4,5,6,7,8,"test"]

for fetch in test:
    print(fetch)

This does the foreach in python 3

test = [0,1,2,3,4,5,6,7,8,"test"]

for fetch in test:
    print(fetch)

回答 5

是的,尽管它使用与for循环相同的语法。

for x in ['a', 'b']: print(x)

Yes, although it uses the same syntax as a for loop.

for x in ['a', 'b']: print(x)

回答 6

如果我没看错,您的意思是如果您具有函数’func’,则您想检查func(item)返回true时列表中的每一项;如果您对所有人都成立,那就做点什么。

您可以使用“全部”。

例如:我想获得列表中0-10范围内的所有素数:

from math import sqrt
primes = [x for x in range(10) if x > 2 and all(x % i !=0 for i in range(2, int(sqrt(x)) + 1))]

If I understood you right, you mean that if you have a function ‘func’, you want to check for each item in list if func(item) returns true; if you get true for all, then do something.

You can use ‘all’.

For example: I want to get all prime numbers in range 0-10 in a list:

from math import sqrt
primes = [x for x in range(10) if x > 2 and all(x % i !=0 for i in range(2, int(sqrt(x)) + 1))]

回答 7

这是可以同时访问Python中元素索引“ foreach”构造示例:

for idx, val in enumerate([3, 4, 5]):
    print (idx, val)

Here is the example of the “foreach” construction with simultaneous access to the element indexes in Python:

for idx, val in enumerate([3, 4, 5]):
    print (idx, val)

回答 8

这篇文章。迭代器对象nditernumpy的包,在NumPy的1.6引入,提供了许多灵活的方式来访问一个或多个阵列的所有元素以系统的方式。

例:

import random
import numpy as np

ptrs = np.int32([[0, 0], [400, 0], [0, 400], [400, 400]])

for ptr in np.nditer(ptrs, op_flags=['readwrite']):
    # apply random shift on 1 for each element of the matrix
    ptr += random.choice([-1, 1])

print(ptrs)

d:\>python nditer.py
[[ -1   1]
 [399  -1]
 [  1 399]
 [399 401]]

Look at this article. The iterator object nditer from numpy package, introduced in NumPy 1.6, provides many flexible ways to visit all the elements of one or more arrays in a systematic fashion.

Example:

import random
import numpy as np

ptrs = np.int32([[0, 0], [400, 0], [0, 400], [400, 400]])

for ptr in np.nditer(ptrs, op_flags=['readwrite']):
    # apply random shift on 1 for each element of the matrix
    ptr += random.choice([-1, 1])

print(ptrs)

d:\>python nditer.py
[[ -1   1]
 [399  -1]
 [  1 399]
 [399 401]]

回答 9

如果您只是在寻找一种更简洁的语法,可以将for循环放在一行上:

array = ['a', 'b']
for value in array: print(value)

只需用分号分隔其他语句即可。

array = ['a', 'b']
for value in array: print(value); print('hello')

这可能不符合您的本地风格指南,但是在控制台中玩耍时这样做可能是有道理的。

If you’re just looking for a more concise syntax you can put the for loop on one line:

array = ['a', 'b']
for value in array: print(value)

Just separate additional statements with a semicolon.

array = ['a', 'b']
for value in array: print(value); print('hello')

This may not conform to your local style guide, but it could make sense to do it like this when you’re playing around in the console.


回答 10

我认为这回答了您的问题,因为它就像一个“ for each”循环。
以下脚本在python(版本3.8)中有效:

a=[1,7,77,7777,77777,777777,7777777,765,456,345,2342,4]
if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

I think this answers your question, because it is like a “for each” loop.
The script below is valid in python (version 3.8):

a=[1,7,77,7777,77777,777777,7777777,765,456,345,2342,4]
if (n := len(a)) > 10:
    print(f"List is too long ({n} elements, expected <= 10)")

Python整数除法产生浮点数

问题:Python整数除法产生浮点数

Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 2/2
1.0

这是故意的吗?我强烈记得以前的版本返回了int/int=int吗?我该怎么办,有没有新的分公司运营商,或者我必须始终选拔?

Python 3.1 (r31:73574, Jun 26 2009, 20:21:35) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 2/2
1.0

Is this intended? I strongly remember earlier versions returning int/int=int? What should I do, is there a new division operator or must I always cast?


回答 0

看看PEP-238:更改除法运算符

//运算符将可用于明确要求楼层分割。

Take a look at PEP-238: Changing the Division Operator

The // operator will be available to request floor division unambiguously.


回答 1

糟糕,立即发现2//2

Oops, immediately found 2//2.


回答 2

希望它可以立即帮助某人。

Python 2.7和Python 3中除法运算符的行为

在Python 2.7中:默认情况下,除法运算符将返回整数输出。

将结果以1.0的两倍倍数除以 “除数或除数”

100/35 => 2 #(Expected is 2.857142857142857)
(100*1.0)/35 => 2.857142857142857
100/(35*1.0) => 2.857142857142857

在Python 3中

// => used for integer output
/ => used for double output

100/35 => 2.857142857142857
100//35 => 2
100.//35 => 2.0    # floating-point result if divsor or dividend real

Hope it might help someone instantly.

Behavior of Division Operator in Python 2.7 and Python 3

In Python 2.7: By default, division operator will return integer output.

to get the result in double multiple 1.0 to “dividend or divisor”

100/35 => 2 #(Expected is 2.857142857142857)
(100*1.0)/35 => 2.857142857142857
100/(35*1.0) => 2.857142857142857

In Python 3

// => used for integer output
/ => used for double output

100/35 => 2.857142857142857
100//35 => 2
100.//35 => 2.0    # floating-point result if divsor or dividend real

回答 3

接受的答案已经提到了PEP 238。我只想为那些对正在发生的事情感兴趣的人快速了解幕后情况,而无需阅读整个PEP。

Python将运算符+-,,*和)映射/到特殊函数,例如a + b相当于

a.__add__(b)

关于在Python 2分割,存在通过仅仅默认/映射到__div__,其结果是依赖于输入类型(例如intfloat)。

Python 2.2引入了__future__功能division,该功能通过以下方式更改了分割语义(PEP 238的TL; DR):

  • /__truediv__必须“返回除法的数学结果的合理近似值”的映射(来自PEP 238的引用)
  • //映射到__floordiv__,应返回的底数结果/

在Python 3.0中,PEP 238的更改成为默认行为,并且__div__Python对象模型中没有其他特殊方法。

如果要在Python 2和Python 3中使用相同的代码,请使用

from __future__ import division

并坚持到PEP的238个语义///

The accepted answer already mentions PEP 238. I just want to add a quick look behind the scenes for those interested in what’s going on without reading the whole PEP.

Python maps operators like +, -, * and / to special functions, such that e.g. a + b is equivalent to

a.__add__(b)

Regarding division in Python 2, there is by default only / which maps to __div__ and the result is dependent on the input types (e.g. int, float).

Python 2.2 introduced the __future__ feature division, which changed the division semantics the following way (TL;DR of PEP 238):

  • / maps to __truediv__ which must “return a reasonable approximation of the mathematical result of the division” (quote from PEP 238)
  • // maps to __floordiv__, which should return the floored result of /

With Python 3.0, the changes of PEP 238 became the default behaviour and there is no more special method __div__ in Python’s object model.

If you want to use the same code in Python 2 and Python 3 use

from __future__ import division

and stick to the PEP 238 semantics of / and //.


回答 4

根据Python3文档,python除以整数后,尽管预期为整数,但仍会生成浮点数。

对于仅打印整数,请使用floor division method。楼层除法将四舍五入并除去小数点。Represented by //

因此,使用2/2代替 2//2

__future__无论使用python2还是python3,也可以从中导入除法。

希望能帮助到你!

According to Python3 documentation,python when divided by integer,will generate float despite expected to be integer.

For exclusively printing integer,use floor division method. Floor division is rounding off zero and removing decimal point. Represented by //

Hence,instead of 2/2 ,use 2//2

You can also import division from __future__ irrespective of using python2 or python3.

Hope it helps!