分类目录归档:知识问答

如何使用Python从字符串中删除字符

问题:如何使用Python从字符串中删除字符

例如,有一个字符串。EXAMPLE

如何从中删除中间字符M?我不需要代码。我想知道:

  • Python中的字符串是否以任何特殊字符结尾?
  • 哪种更好的方法-从中间字符开始或从创建新字符串开始,将所有内容从右移到左,而不是复制中间字符?

There is a string, for example. EXAMPLE.

How can I remove the middle character, i.e., M from it? I don’t need the code. I want to know:

  • Do strings in Python end in any special character?
  • Which is a better way – shifting everything right to left starting from the middle character OR creation of a new string and not copying the middle character?

回答 0

在Python中,字符串是不可变的,因此您必须创建一个新字符串。您有一些有关如何创建新字符串的选项。如果要删除出现的“ M”,请执行以下操作:

newstr = oldstr.replace("M", "")

如果要删除中心字符:

midlen = len(oldstr)/2   # //2 in python 3
newstr = oldstr[:midlen] + oldstr[midlen+1:]

您询问字符串是否以特殊字符结尾。不,您在想像C程序员。在Python中,字符串按其长度存储,因此任何字节值(包括\0)都可以出现在字符串中。

In Python, strings are immutable, so you have to create a new string. You have a few options of how to create the new string. If you want to remove the ‘M’ wherever it appears:

newstr = oldstr.replace("M", "")

If you want to remove the central character:

midlen = len(oldstr)/2   # //2 in python 3
newstr = oldstr[:midlen] + oldstr[midlen+1:]

You asked if strings end with a special character. No, you are thinking like a C programmer. In Python, strings are stored with their length, so any byte value, including \0, can appear in a string.


回答 1

这可能是最好的方法:

original = "EXAMPLE"
removed = original.replace("M", "")

不用担心字符转移等问题。大多数Python代码以更高的抽象级别进行。

This is probably the best way:

original = "EXAMPLE"
removed = original.replace("M", "")

Don’t worry about shifting characters and such. Most Python code takes place on a much higher level of abstraction.


回答 2

要替换特定职位:

s = s[:pos] + s[(pos+1):]

替换特定字符:

s = s.replace('M','')

To replace a specific position:

s = s[:pos] + s[(pos+1):]

To replace a specific character:

s = s.replace('M','')

回答 3

字符串是不可变的。但是您可以将它们转换为可变的列表,然后在更改列表后将其转换回字符串。

s = "this is a string"

l = list(s)  # convert to list

l[1] = ""    # "delete" letter h (the item actually still exists but is empty)
l[1:2] = []  # really delete letter h (the item is actually removed from the list)
del(l[1])    # another way to delete it

p = l.index("a")  # find position of the letter "a"
del(l[p])         # delete it

s = "".join(l)  # convert back to string

您还可以通过从现有字符串中获取所需字符以外的所有内容来创建一个新字符串,如其他字符串所示。

Strings are immutable. But you can convert them to a list, which is mutable, and then convert the list back to a string after you’ve changed it.

s = "this is a string"

l = list(s)  # convert to list

l[1] = ""    # "delete" letter h (the item actually still exists but is empty)
l[1:2] = []  # really delete letter h (the item is actually removed from the list)
del(l[1])    # another way to delete it

p = l.index("a")  # find position of the letter "a"
del(l[p])         # delete it

s = "".join(l)  # convert back to string

You can also create a new string, as others have shown, by taking everything except the character you want from the existing string.


回答 4

如何从中删除中间字符(即M)?

您不能,因为Python中的字符串是不可变的

Python中的字符串是否以任何特殊字符结尾?

不。它们类似于字符列表。列表的长度定义字符串的长度,并且没有字符充当终止符。

哪种更好的方法-从中间字符开始或从创建新字符串开始,将所有内容从右移到左,而不是复制中间字符?

您无法修改现有字符串,因此必须创建一个新字符串,其中包含除中间字符以外的所有内容。

How can I remove the middle character, i.e., M from it?

You can’t, because strings in Python are immutable.

Do strings in Python end in any special character?

No. They are similar to lists of characters; the length of the list defines the length of the string, and no character acts as a terminator.

Which is a better way – shifting everything right to left starting from the middle character OR creation of a new string and not copying the middle character?

You cannot modify the existing string, so you must create a new one containing everything except the middle character.


回答 5

使用translate()方法:

>>> s = 'EXAMPLE'
>>> s.translate(None, 'M')
'EXAPLE'

Use the translate() method:

>>> s = 'EXAMPLE'
>>> s.translate(None, 'M')
'EXAPLE'

回答 6

UserString.MutableString

可变方式:

import UserString

s = UserString.MutableString("EXAMPLE")

>>> type(s)
<type 'str'>

# Delete 'M'
del s[3]

# Turn it for immutable:
s = str(s)

UserString.MutableString

Mutable way:

import UserString

s = UserString.MutableString("EXAMPLE")

>>> type(s)
<type 'str'>

# Delete 'M'
del s[3]

# Turn it for immutable:
s = str(s)

回答 7

card = random.choice(cards)
cardsLeft = cards.replace(card, '', 1)

如何从字符串中删除一个字符: 这是一个示例,其中有一堆卡表示为字符串中的字符。其中一个被绘制(为random.choice()函数导入random模块,该函数从字符串中选择一个随机字符)。创建了一个新字符串cardsLeft,以容纳由字符串函数replace()给出的剩余卡片,其中最后一个参数指示仅一个“卡片”将被空字符串替换…

card = random.choice(cards)
cardsLeft = cards.replace(card, '', 1)

How to remove one character from a string: Here is an example where there is a stack of cards represented as characters in a string. One of them is drawn (import random module for the random.choice() function, that picks a random character in the string). A new string, cardsLeft, is created to hold the remaining cards given by the string function replace() where the last parameter indicates that only one “card” is to be replaced by the empty string…


回答 8

def kill_char(string, n): # n = position of which character you want to remove
    begin = string[:n]    # from beginning to n (n not included)
    end = string[n+1:]    # n+1 through end of string
    return begin + end
print kill_char("EXAMPLE", 3)  # "M" removed

我看到这个地方在这里

def kill_char(string, n): # n = position of which character you want to remove
    begin = string[:n]    # from beginning to n (n not included)
    end = string[n+1:]    # n+1 through end of string
    return begin + end
print kill_char("EXAMPLE", 3)  # "M" removed

I have seen this somewhere here.


回答 9

这是我切出“ M”的方法:

s = 'EXAMPLE'
s1 = s[:s.index('M')] + s[s.index('M')+1:]

Here’s what I did to slice out the “M”:

s = 'EXAMPLE'
s1 = s[:s.index('M')] + s[s.index('M')+1:]

回答 10

如果您要删除/忽略字符串中的字符,例如,您拥有此字符串,

“ [11:L:0]”

来自Web API响应或类似CSV文件之类的信息,假设您正在使用请求

import requests
udid = 123456
url = 'http://webservices.yourserver.com/action/id-' + udid
s = requests.Session()
s.verify = False
resp = s.get(url, stream=True)
content = resp.content

循环并摆脱不需要的字符:

for line in resp.iter_lines():
  line = line.replace("[", "")
  line = line.replace("]", "")
  line = line.replace('"', "")

可选拆分,您将能够单独读取值:

listofvalues = line.split(':')

现在访问每个值更容易:

print listofvalues[0]
print listofvalues[1]
print listofvalues[2]

这将打印

11

大号

0

If you want to delete/ignore characters in a string, and, for instance, you have this string,

“[11:L:0]”

from a web API response or something like that, like a CSV file, let’s say you are using requests

import requests
udid = 123456
url = 'http://webservices.yourserver.com/action/id-' + udid
s = requests.Session()
s.verify = False
resp = s.get(url, stream=True)
content = resp.content

loop and get rid of unwanted chars:

for line in resp.iter_lines():
  line = line.replace("[", "")
  line = line.replace("]", "")
  line = line.replace('"', "")

Optional split, and you will be able to read values individually:

listofvalues = line.split(':')

Now accessing each value is easier:

print listofvalues[0]
print listofvalues[1]
print listofvalues[2]

This will print

11

L

0


回答 11

删除一次charsub-string 一次(仅第一次出现):

main_string = main_string.replace(sub_str, replace_with, 1)

注意:在这里1可以用任何int您要替换的出现次数替换。

To delete a char or a sub-string once (only the first occurrence):

main_string = main_string.replace(sub_str, replace_with, 1)

NOTE: Here 1 can be replaced with any int for the number of occurrence you want to replace.


回答 12

您可以简单地使用列表理解。

假设您有字符串:,my name is并且想要删除character m。使用以下代码:

"".join([x for x in "my name is" if x is not 'm'])

You can simply use list comprehension.

Assume that you have the string: my name is and you want to remove character m. use the following code:

"".join([x for x in "my name is" if x is not 'm'])

回答 13

from random import randint


def shuffle_word(word):
    newWord=""
    for i in range(0,len(word)):
        pos=randint(0,len(word)-1)
        newWord += word[pos]
        word = word[:pos]+word[pos+1:]
    return newWord

word = "Sarajevo"
print(shuffle_word(word))
from random import randint


def shuffle_word(word):
    newWord=""
    for i in range(0,len(word)):
        pos=randint(0,len(word)-1)
        newWord += word[pos]
        word = word[:pos]+word[pos+1:]
    return newWord

word = "Sarajevo"
print(shuffle_word(word))

回答 14

另一种方法是使用函数

下面是一种仅通过调用函数即可从字符串中删除所有元音的方法

def disemvowel(s):
    return s.translate(None, "aeiouAEIOU")

Another way is with a function,

Below is a way to remove all vowels from a string, just by calling the function

def disemvowel(s):
    return s.translate(None, "aeiouAEIOU")

回答 15

字符串在Python中是不可变的,因此您的两个选项基本上意味着同一件事。

Strings are immutable in Python so both your options mean the same thing basically.


如何在熊猫数据框的列中将所有NaN值替换为零

问题:如何在熊猫数据框的列中将所有NaN值替换为零

我有一个数据框如下

      itm Date                  Amount 
67    420 2012-09-30 00:00:00   65211
68    421 2012-09-09 00:00:00   29424
69    421 2012-09-16 00:00:00   29877
70    421 2012-09-23 00:00:00   30990
71    421 2012-09-30 00:00:00   61303
72    485 2012-09-09 00:00:00   71781
73    485 2012-09-16 00:00:00     NaN
74    485 2012-09-23 00:00:00   11072
75    485 2012-09-30 00:00:00  113702
76    489 2012-09-09 00:00:00   64731
77    489 2012-09-16 00:00:00     NaN

当我尝试将一个函数应用于“金额”列时,出现以下错误。

ValueError: cannot convert float NaN to integer

我已经尝试过使用数学模块中的.isnan来应用函数。我已经尝试过pandas .replace属性。我已经尝试过pandas 0.9的.sparse data属性。我还尝试过如果函数中的NaN == NaN语句。我还看了这篇文章如何在R数据帧中用零替换NA值?同时查看其他文章。我尝试过的所有方法均无效或无法识别NaN。任何提示或解决方案将不胜感激。

I have a dataframe as below

      itm Date                  Amount 
67    420 2012-09-30 00:00:00   65211
68    421 2012-09-09 00:00:00   29424
69    421 2012-09-16 00:00:00   29877
70    421 2012-09-23 00:00:00   30990
71    421 2012-09-30 00:00:00   61303
72    485 2012-09-09 00:00:00   71781
73    485 2012-09-16 00:00:00     NaN
74    485 2012-09-23 00:00:00   11072
75    485 2012-09-30 00:00:00  113702
76    489 2012-09-09 00:00:00   64731
77    489 2012-09-16 00:00:00     NaN

when I try to .apply a function to the Amount column I get the following error.

ValueError: cannot convert float NaN to integer

I have tried applying a function using .isnan from the Math Module I have tried the pandas .replace attribute I tried the .sparse data attribute from pandas 0.9 I have also tried if NaN == NaN statement in a function. I have also looked at this article How do I replace NA values with zeros in an R dataframe? whilst looking at some other articles. All the methods I have tried have not worked or do not recognise NaN. Any Hints or solutions would be appreciated.


回答 0

我相信DataFrame.fillna()会为您做到这一点。

链接到文档以获取数据框系列

例:

In [7]: df
Out[7]: 
          0         1
0       NaN       NaN
1 -0.494375  0.570994
2       NaN       NaN
3  1.876360 -0.229738
4       NaN       NaN

In [8]: df.fillna(0)
Out[8]: 
          0         1
0  0.000000  0.000000
1 -0.494375  0.570994
2  0.000000  0.000000
3  1.876360 -0.229738
4  0.000000  0.000000

要仅将NaN填入一列,请仅选择该列。在这种情况下,我使用inplace = True实际更改df的内容。

In [12]: df[1].fillna(0, inplace=True)
Out[12]: 
0    0.000000
1    0.570994
2    0.000000
3   -0.229738
4    0.000000
Name: 1

In [13]: df
Out[13]: 
          0         1
0       NaN  0.000000
1 -0.494375  0.570994
2       NaN  0.000000
3  1.876360 -0.229738
4       NaN  0.000000

编辑:

为避免出现SettingWithCopyWarning,请使用内置的列专用功能:

df.fillna({1:0}, inplace=True)

I believe DataFrame.fillna() will do this for you.

Link to Docs for a dataframe and for a Series.

Example:

In [7]: df
Out[7]: 
          0         1
0       NaN       NaN
1 -0.494375  0.570994
2       NaN       NaN
3  1.876360 -0.229738
4       NaN       NaN

In [8]: df.fillna(0)
Out[8]: 
          0         1
0  0.000000  0.000000
1 -0.494375  0.570994
2  0.000000  0.000000
3  1.876360 -0.229738
4  0.000000  0.000000

To fill the NaNs in only one column, select just that column. in this case I’m using inplace=True to actually change the contents of df.

In [12]: df[1].fillna(0, inplace=True)
Out[12]: 
0    0.000000
1    0.570994
2    0.000000
3   -0.229738
4    0.000000
Name: 1

In [13]: df
Out[13]: 
          0         1
0       NaN  0.000000
1 -0.494375  0.570994
2       NaN  0.000000
3  1.876360 -0.229738
4       NaN  0.000000

EDIT:

To avoid a SettingWithCopyWarning, use the built in column-specific functionality:

df.fillna({1:0}, inplace=True)

回答 1

不能保证切片会返回视图或副本。你可以做

df['column'] = df['column'].fillna(value)

It is not guaranteed that the slicing returns a view or a copy. You can do

df['column'] = df['column'].fillna(value)

回答 2

您可以使用replace更改NaN0

import pandas as pd
import numpy as np

# for column
df['column'] = df['column'].replace(np.nan, 0)

# for whole dataframe
df = df.replace(np.nan, 0)

# inplace
df.replace(np.nan, 0, inplace=True)

You could use replace to change NaN to 0:

import pandas as pd
import numpy as np

# for column
df['column'] = df['column'].replace(np.nan, 0)

# for whole dataframe
df = df.replace(np.nan, 0)

# inplace
df.replace(np.nan, 0, inplace=True)

回答 3

我只是想提供一些更新/特殊情况,因为看起来人们仍然来这里。如果您使用的是多索引或以其他方式使用索引切片器,则inplace = True选项可能不足以更新您选择的切片。例如,在2×2级多索引中,这不会更改任何值(从熊猫0.15开始):

idx = pd.IndexSlice
df.loc[idx[:,mask_1],idx[mask_2,:]].fillna(value=0,inplace=True)

“问题”是链接中断了fillna更新原始数据帧的能力。我将“问题”用引号引起来,因为设计决策有充分的理由导致在某些情况下无法通过这些链条进行解释。同样,这是一个复杂的示例(尽管我确实遇到过),但是根据切片的方式,同样的情况可能适用于较少级别的索引。

解决方案是DataFrame.update:

df.update(df.loc[idx[:,mask_1],idx[[mask_2],:]].fillna(value=0))

这是一行,读起来相当好(某种),并消除了中间变量或循环的不必要混乱,同时允许您将fillna应用于所需的任何多层次切片!

如果有人可以找到行不通的地方,请在评论中发帖,我一直在弄乱它并查看源代码,它似乎至少解决了我的多索引切片问题。

I just wanted to provide a bit of an update/special case since it looks like people still come here. If you’re using a multi-index or otherwise using an index-slicer the inplace=True option may not be enough to update the slice you’ve chosen. For example in a 2×2 level multi-index this will not change any values (as of pandas 0.15):

idx = pd.IndexSlice
df.loc[idx[:,mask_1],idx[mask_2,:]].fillna(value=0,inplace=True)

The “problem” is that the chaining breaks the fillna ability to update the original dataframe. I put “problem” in quotes because there are good reasons for the design decisions that led to not interpreting through these chains in certain situations. Also, this is a complex example (though I really ran into it), but the same may apply to fewer levels of indexes depending on how you slice.

The solution is DataFrame.update:

df.update(df.loc[idx[:,mask_1],idx[[mask_2],:]].fillna(value=0))

It’s one line, reads reasonably well (sort of) and eliminates any unnecessary messing with intermediate variables or loops while allowing you to apply fillna to any multi-level slice you like!

If anybody can find places this doesn’t work please post in the comments, I’ve been messing with it and looking at the source and it seems to solve at least my multi-index slice problems.


回答 4

下面的代码为我工作。

import pandas

df = pandas.read_csv('somefile.txt')

df = df.fillna(0)

The below code worked for me.

import pandas

df = pandas.read_csv('somefile.txt')

df = df.fillna(0)

回答 5

填充缺失值的简单方法:

填充 字符串列:当字符串列具有缺失值和NaN值时。

df['string column name'].fillna(df['string column name'].mode().values[0], inplace = True)

填充 数字列:当数字列缺少值和NaN值时。

df['numeric column name'].fillna(df['numeric column name'].mean(), inplace = True)

用零填充NaN:

df['column name'].fillna(0, inplace = True)

Easy way to fill the missing values:-

filling string columns: when string columns have missing values and NaN values.

df['string column name'].fillna(df['string column name'].mode().values[0], inplace = True)

filling numeric columns: when the numeric columns have missing values and NaN values.

df['numeric column name'].fillna(df['numeric column name'].mean(), inplace = True)

filling NaN with zero:

df['column name'].fillna(0, inplace = True)

回答 6

您还可以使用字典来填充DataFrame中特定列的NaN值,而不是使用某个oneValue来填充所有DF。

import pandas as pd

df = pd.read_excel('example.xlsx')
df.fillna( {
        'column1': 'Write your values here',
        'column2': 'Write your values here',
        'column3': 'Write your values here',
        'column4': 'Write your values here',
        .
        .
        .
        'column-n': 'Write your values here'} , inplace=True)

You can also use dictionaries to fill NaN values of the specific columns in the DataFrame rather to fill all the DF with some oneValue.

import pandas as pd

df = pd.read_excel('example.xlsx')
df.fillna( {
        'column1': 'Write your values here',
        'column2': 'Write your values here',
        'column3': 'Write your values here',
        'column4': 'Write your values here',
        .
        .
        .
        'column-n': 'Write your values here'} , inplace=True)

回答 7

在此处输入图片说明

考虑到Amount上表中的特定列是整数类型。以下是一个解决方案:

df['Amount'] = df.Amount.fillna(0).astype(int)

同样,你可以用不同的数据类型,如填充它floatstr等等。

特别是,我会考虑使用数据类型来比较同一列的各种值。

enter image description here

Considering the particular column Amount in the above table is of integer type. The following would be a solution :

df['Amount'] = df.Amount.fillna(0).astype(int)

Similarly, you can fill it with various data types like float, str and so on.

In particular, I would consider datatype to compare various values of the same column.


回答 8

替换熊猫中的na值

df['column_name'].fillna(value_to_be_replaced,inplace=True)

如果为inplace = False,则不更新df(数据帧),而是返回修改后的值。

To replace na values in pandas

df['column_name'].fillna(value_to_be_replaced,inplace=True)

if inplace = False, instead of updating the df (dataframe) it will return the modified values.


回答 9

如果要将其转换为pandas数据框,也可以使用来完成此操作fillna

import numpy as np
df=np.array([[1,2,3, np.nan]])

import pandas as pd
df=pd.DataFrame(df)
df.fillna(0)

这将返回以下内容:

     0    1    2   3
0  1.0  2.0  3.0 NaN
>>> df.fillna(0)
     0    1    2    3
0  1.0  2.0  3.0  0.0

If you were to convert it to a pandas dataframe, you can also accomplish this by using fillna.

import numpy as np
df=np.array([[1,2,3, np.nan]])

import pandas as pd
df=pd.DataFrame(df)
df.fillna(0)

This will return the following:

     0    1    2   3
0  1.0  2.0  3.0 NaN
>>> df.fillna(0)
     0    1    2    3
0  1.0  2.0  3.0  0.0

回答 10

主要有两个选项:插补或填充缺失值的情况下NaN / np.nan,仅数字替换(跨列:

df['Amount'].fillna(value=None, method= ,axis=1,) 足够了:

从文档中:

value:标量,dict,Series或DataFrame用于填充孔的值(例如0),或者是dict / Series / DataFrame的值,这些值指定每个索引(对于Series)或列(对于DataFrame)使用哪个值。(不在dict / Series / DataFrame中的值将不被填充)。该值不能是列表。

这意味着不再允许对“字符串”或“常量”进行插补。

对于更专业的插补,请使用SimpleImputer()

from sklearn.impute import SimpleImputer
si = SimpleImputer(strategy='constant', missing_values=np.nan, fill_value='Replacement_Value')
df[['Col-1', 'Col-2']] = si.fit_transform(X=df[['C-1', 'C-2']])

There are two options available primarily; in case of imputation or filling of missing values NaN / np.nan with only numerical replacements (across column(s):

df['Amount'].fillna(value=None, method= ,axis=1,) is sufficient:

From the Documentation:

value : scalar, dict, Series, or DataFrame Value to use to fill holes (e.g. 0), alternately a dict/Series/DataFrame of values specifying which value to use for each index (for a Series) or column (for a DataFrame). (values not in the dict/Series/DataFrame will not be filled). This value cannot be a list.

Which means ‘strings’ or ‘constants’ are no longer permissable to be imputed.

For more specialized imputations use SimpleImputer():

from sklearn.impute import SimpleImputer
si = SimpleImputer(strategy='constant', missing_values=np.nan, fill_value='Replacement_Value')
df[['Col-1', 'Col-2']] = si.fit_transform(X=df[['C-1', 'C-2']])


回答 11

用不同的方式替换不同列中的nan:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)

To replace nan in different columns with different ways:

   replacement= {'column_A': 0, 'column_B': -999, 'column_C': -99999}
   df.fillna(value=replacement)

我已经安装了哪个版本的Python?

问题:我已经安装了哪个版本的Python?

我必须在Windows服务器上运行Python脚本。我怎么知道我拥有哪个版本的Python,它真的很重要吗?

我当时想更新到最新版本的Python。

I have to run a Python script on a Windows server. How can I know which version of Python I have, and does it even really matter?

I was thinking of updating to the latest version of Python.


回答 0

python -V

http://docs.python.org/using/cmdline.html#generic-options

--version 可能也可以使用(在2.5版中引入)

python -V

http://docs.python.org/using/cmdline.html#generic-options

--version may also work (introduced in version 2.5)


回答 1

Python 2.5以上版本:

python --version

Python 2.4-:

python -c 'import sys; print(sys.version)'

Python 2.5+:

python --version

Python 2.4-:

python -c 'import sys; print(sys.version)'

回答 2

在Python IDE中,只需复制并粘贴以下代码并运行它(版本将显示在输出区域中):

import sys
print(sys.version)

In a Python IDE, just copy and paste in the following code and run it (the version will come up in the output area):

import sys
print(sys.version)

回答 3

在命令提示符下键入:

python -V

或者,如果您有pyenv:

pyenv versions

At a command prompt type:

python -V

Or if you have pyenv:

pyenv versions

回答 4

当我打开Python (command line)第一件事时,它会告诉我版本。

When I open Python (command line) the first thing it tells me is the version.


回答 5

尽管问题是“我正在使用哪个版本?”,但这实际上可能并不是您需要知道的所有内容。您可能安装了其他版本,这可能会导致问题,尤其是在安装其他模块时。这是我了解安装了哪些版本的粗略方法:

updatedb                  # Be in root for this
locate site.py            # All installations I've ever seen have this

单个Python安装的输出应如下所示:

/usr/lib64/python2.7/site.py
/usr/lib64/python2.7/site.pyc
/usr/lib64/python2.7/site.pyo

多个安装将输出如下内容:

/root/Python-2.7.6/Lib/site.py
/root/Python-2.7.6/Lib/site.pyc
/root/Python-2.7.6/Lib/site.pyo
/root/Python-2.7.6/Lib/test/test_site.py
/usr/lib/python2.6/site-packages/site.py
/usr/lib/python2.6/site-packages/site.pyc
/usr/lib/python2.6/site-packages/site.pyo
/usr/lib64/python2.6/site.py
/usr/lib64/python2.6/site.pyc
/usr/lib64/python2.6/site.pyo
/usr/local/lib/python2.7/site.py
/usr/local/lib/python2.7/site.pyc
/usr/local/lib/python2.7/site.pyo
/usr/local/lib/python2.7/test/test_site.py
/usr/local/lib/python2.7/test/test_site.pyc
/usr/local/lib/python2.7/test/test_site.pyo

Although the question is “which version am I using?”, this may not actually be everything you need to know. You may have other versions installed and this can cause problems, particularly when installing additional modules. This is my rough-and-ready approach to finding out what versions are installed:

updatedb                  # Be in root for this
locate site.py            # All installations I've ever seen have this

The output for a single Python installation should look something like this:

/usr/lib64/python2.7/site.py
/usr/lib64/python2.7/site.pyc
/usr/lib64/python2.7/site.pyo

Multiple installations will have output something like this:

/root/Python-2.7.6/Lib/site.py
/root/Python-2.7.6/Lib/site.pyc
/root/Python-2.7.6/Lib/site.pyo
/root/Python-2.7.6/Lib/test/test_site.py
/usr/lib/python2.6/site-packages/site.py
/usr/lib/python2.6/site-packages/site.pyc
/usr/lib/python2.6/site-packages/site.pyo
/usr/lib64/python2.6/site.py
/usr/lib64/python2.6/site.pyc
/usr/lib64/python2.6/site.pyo
/usr/local/lib/python2.7/site.py
/usr/local/lib/python2.7/site.pyc
/usr/local/lib/python2.7/site.pyo
/usr/local/lib/python2.7/test/test_site.py
/usr/local/lib/python2.7/test/test_site.pyc
/usr/local/lib/python2.7/test/test_site.pyo

回答 6

In [1]: import sys

In [2]: sys.version
2.7.11 |Anaconda 2.5.0 (64-bit)| (default, Dec  6 2015, 18:08:32) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]

In [3]: sys.version_info
sys.version_info(major=2, minor=7, micro=11, releaselevel='final', serial=0)

In [4]: sys.version_info >= (2,7)
Out[4]: True

In [5]: sys.version_info >= (3,)
Out[5]: False
In [1]: import sys

In [2]: sys.version
2.7.11 |Anaconda 2.5.0 (64-bit)| (default, Dec  6 2015, 18:08:32) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]

In [3]: sys.version_info
sys.version_info(major=2, minor=7, micro=11, releaselevel='final', serial=0)

In [4]: sys.version_info >= (2,7)
Out[4]: True

In [5]: sys.version_info >= (3,)
Out[5]: False

回答 7

简而言之:

键入python在命令提示

只需打开命令提示符(Win+ R)并键入,cmd然后在命令提示符中键入,即可python为您提供有关版本的所有必要信息:

Python版本

In short:

Type python in a command prompt

Simply open the command prompt (Win + R) and type cmd and in the command prompt then typing python will give you all necessary information regarding versions:

Python version


回答 8

>>> import sys; print('{0[0]}.{0[1]}'.format(sys.version_info))
3.5

所以从命令行:

python -c "import sys; print('{0[0]}.{0[1]}'.format(sys.version_info))"
>>> import sys; print('{0[0]}.{0[1]}'.format(sys.version_info))
3.5

so from the command line:

python -c "import sys; print('{0[0]}.{0[1]}'.format(sys.version_info))"

回答 9

采用

python -V

要么

python --version

注意:请注意,python -V命令中的“ V” 为大写V。python -v(小“ v”)将以详细模式启动Python。

Use

python -V

or

python --version

NOTE: Please note that the “V” in the python -V command is capital V. python -v (small “v”) will launch Python in verbose mode.


回答 10

您可以使用以下命令获取Python的版本

python --version

您甚至可以使用以下命令获取venv中安装的任何软件包的版本pip freeze

pip freeze | grep "package name"

或将Python解释器用作:

In [1]: import django
In [2]: django.VERSION
Out[2]: (1, 6, 1, 'final', 0)

You can get the version of Python by using the following command

python --version

You can even get the version of any package installed in venv using pip freeze as:

pip freeze | grep "package name"

Or using the Python interpreter as:

In [1]: import django
In [2]: django.VERSION
Out[2]: (1, 6, 1, 'final', 0)

回答 11

我在Windows 10上使用Python 3.7.0。

这是在命令提示符和Git Bash中对我有用的方法

要运行Python并检查版本:

py

仅检查您拥有的版本:

py --version

要么

py -V    # Make sure it is a capital V

注:pythonpython --versionpython -VPythonPython --versionPython -V并没有为我工作。

I have Python 3.7.0 on Windows 10.

This is what worked for me in the command prompt and Git Bash:

To run Python and check the version:

py

To only check which version you have:

py --version

or

py -V    # Make sure it is a capital V

Note: python, python --version, python -V,Python, Python --version, Python -V did not work for me.


回答 12

如果您已经在REPL窗口中,但没有看到带有版本号的欢迎消息,则可以使用help()查看主要版本和次要版本:

>>>help()
Welcome to Python 3.6's help utility!
...

If you are already in a REPL window and don’t see the welcome message with the version number, you can use help() to see the major and minor version:

>>>help()
Welcome to Python 3.6's help utility!
...

回答 13

要在Jupyter笔记本中检查Python版本,可以使用:

from platform import python_version
print(python_version())

获取版本号,例如:

3.7.3

要么:

import sys
print(sys.version)

以获取更多信息

3.7.3 (default, Apr 24 2019, 13:20:13) [MSC v.1915 32 bit (Intel)]

要么:

sys.version_info

获得主要版本,次要版本和微型版本

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

To check the Python version in a Jupyter notebook, you can use:

from platform import python_version
print(python_version())

to get version number, as:

3.7.3

or:

import sys
print(sys.version)

to get more information, as

3.7.3 (default, Apr 24 2019, 13:20:13) [MSC v.1915 32 bit (Intel)]

or:

sys.version_info

to get major, minor and micro versions, as

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

回答 14

只需创建一个以.py结尾的文件,然后将以下代码粘贴到并运行即可。

#!/usr/bin/python3.6

import platform
import sys

def linux_dist():
  try:
    return platform.linux_distribution()
  except:
    return "N/A"

print("""Python version: %s
dist: %s
linux_distribution: %s
system: %s
machine: %s
platform: %s
uname: %s
version: %s
""" % (
sys.version.split('\n'),
str(platform.dist()),
linux_dist(),
platform.system(),
platform.machine(),
platform.platform(),
platform.uname(),
platform.version(),
))

如果系统上安装了多个Python解释器版本,请运行以下命令。

在Linux上,在终端上运行:

ll /usr/bin/python*

在Windows上,在命令提示符下运行:

dir %LOCALAPPDATA%\Programs\Python

Just create a file ending with .py and paste the code below into and run it.

#!/usr/bin/python3.6

import platform
import sys

def linux_dist():
  try:
    return platform.linux_distribution()
  except:
    return "N/A"

print("""Python version: %s
dist: %s
linux_distribution: %s
system: %s
machine: %s
platform: %s
uname: %s
version: %s
""" % (
sys.version.split('\n'),
str(platform.dist()),
linux_dist(),
platform.system(),
platform.machine(),
platform.platform(),
platform.uname(),
platform.version(),
))

If several Python interpreter versions are installed on a system, run the following commands.

On Linux, run in a terminal:

ll /usr/bin/python*

On Windows, run in a command prompt:

dir %LOCALAPPDATA%\Programs\Python

回答 15

要在Windows上验证Python版本的命令,请在命令提示符下运行以下命令并验证输出:

c:\> python -V
Python 2.7.16

c:\> py -2 -V
Python 2.7.16

c:\> py -3 -V
Python 3.7.3

另外,要查看每个Python版本的文件夹配置,请运行以下命令:

For Python 2, 'py -2 -m site'
For Python 3, 'py -3 -m site'

To verify the Python version for commands on Windows, run the following commands in a command prompt and verify the output:

c:\> python -V
Python 2.7.16

c:\> py -2 -V
Python 2.7.16

c:\> py -3 -V
Python 3.7.3

Also, to see the folder configuration for each Python version, run the following commands:

For Python 2, 'py -2 -m site'
For Python 3, 'py -3 -m site'

回答 16

在具有Python 3.6的Windows 10上

    python

Python 3.6.0a4 (v3.6.0a4:017cf260936b, Aug 16 2016, 00:59:16) [MSC v.1900 64 bit (AMD64)] on win32


    python -V

Python 3.6.0a4


    python --version

Python 3.6.0a4

On Windows 10 with Python 3.6

    python

Python 3.6.0a4 (v3.6.0a4:017cf260936b, Aug 16 2016, 00:59:16) [MSC v.1900 64 bit (AMD64)] on win32


    python -V

Python 3.6.0a4


    python --version

Python 3.6.0a4

回答 17

如果已安装Python,则检查版本号的最简单方法是在命令提示符下键入“ python”。它会显示版本号,以及它是在32位还是64位上运行以及其他信息。对于某些应用程序,您可能需要具有最新版本,而有时却没有。这取决于您要安装或使用的软件包。

If you have Python installed then the easiest way you can check the version number is by typing “python” in your command prompt. It will show you the version number and if it is running on 32 bit or 64 bit and some other information. For some applications you would want to have a latest version and sometimes not. It depends on what packages you want to install or use.


回答 18

对我来说,打开CMD并运行

py

将显示类似

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32

Type "help", "copyright", "credits" or "license" for more information.

For me, opening CMD and running

py

will show something like

Python 3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:43:06) [MSC v.1600 32 bit (Intel)] on win32

Type "help", "copyright", "credits" or "license" for more information.

回答 19

打开命令提示符窗口(按Windows+ R,输入cmd,然后单击Enter)。

类型 python.exe

Open a command prompt window (press Windows + R, type in cmd, and hit Enter).

Type python.exe


回答 20

打字 where python在Windows上命令提示符可能会告诉您在哪里安装了多个不同版本的python,前提是它们已添加到您的路径中。

键入python -V命令提示符将显示版本。

Typing where python on Windows into a Command Prompt may tell you where multiple different versions of python are installed, assuming they have been added to your path.

Typing python -V into the Command Prompt should display the version.


回答 21

主要是用法命令:

python -version

要么

python -V

Mostly usage commands:

python -version

Or

python -V

从子目录导入文件?

问题:从子目录导入文件?

我的档案tester.py位于/project

/project有一个名为的子目录lib,文件名为BoxTime.py

/project/tester.py
/project/lib/BoxTime.py

我想导入BoxTimetester。我已经试过了:

import lib.BoxTime

结果是:

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

任何想法如何BoxTime从子目录导入?

编辑

__init__.py是问题,但不要忘了提及BoxTime作为lib.BoxTime,或使用:

import lib.BoxTime as BT
...
BT.bt_function()

I have a file called tester.py, located on /project.

/project has a subdirectory called lib, with a file called BoxTime.py:

/project/tester.py
/project/lib/BoxTime.py

I want to import BoxTime from tester. I have tried this:

import lib.BoxTime

Which resulted:

Traceback (most recent call last):
  File "./tester.py", line 3, in <module>
    import lib.BoxTime
ImportError: No module named lib.BoxTime

Any ideas how to import BoxTime from the subdirectory?

EDIT

The __init__.py was the problem, but don’t forget to refer to BoxTime as lib.BoxTime, or use:

import lib.BoxTime as BT
...
BT.bt_function()

回答 0

在此处查看Packages文档(第6.4节):http : //docs.python.org/tutorial/modules.html

简而言之,您需要放置一个名为

__init__.py

在“ lib”目录中。

Take a look at the Packages documentation (Section 6.4) here: http://docs.python.org/tutorial/modules.html

In short, you need to put a blank file named

__init__.py

in the “lib” directory.


回答 1

  • 创建一个名为的子目录lib
  • 创建一个名为的空文件lib\__init__.py
  • 在中lib\BoxTime.py,编写如下函数foo()

    def foo():
        print "foo!"
    
  • 在上面目录中的客户机代码中lib,编写:

    from lib import BoxTime
    BoxTime.foo()
    
  • 运行您的客户端代码。你会得到:

    foo!

后来,在Linux中,它看起来像这样:

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py

0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!
  • Create a subdirectory named lib.
  • Create an empty file named lib\__init__.py.
  • In lib\BoxTime.py, write a function foo() like this:

    def foo():
        print "foo!"
    
  • In your client code in the directory above lib, write:

    from lib import BoxTime
    BoxTime.foo()
    
  • Run your client code. You will get:

    foo!
    

Much later — in linux, it would look like this:

% cd ~/tmp
% mkdir lib
% touch lib/__init__.py
% cat > lib/BoxTime.py << EOF
heredoc> def foo():
heredoc>     print "foo!"
heredoc> EOF
% tree lib
lib
├── BoxTime.py
└── __init__.py

0 directories, 2 files
% python 
Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from lib import BoxTime
>>> BoxTime.foo()
foo!

回答 2

您可以尝试将其插入sys.path

sys.path.insert(0, './lib')
import BoxTime

You can try inserting it in sys.path:

sys.path.insert(0, './lib')
import BoxTime

回答 3

我写下来是因为每个人似乎都建议您必须创建lib目录。

您无需命名子目录lib。你能说出它anything提供你把一个__init__.py进去。

您可以通过在Linux shell中输入以下命令来做到这一点:

$ touch anything/__init__.py 

所以现在您有了以下结构:

$ ls anything/
__init__.py
mylib.py

$ ls
main.py

然后,你可以导入mylibmain.py这样的:

from anything import mylib 

mylib.myfun()

您也可以像这样导入函数和类:

from anything.mylib import MyClass
from anything.mylib import myfun

instance = MyClass()
result = myfun()

您放置在其中的任何变量函数或类__init__.py也可以访问:

import anything

print(anything.myvar)

或像这样:

from anything import myvar

print(myvar)

I am writing this down because everyone seems to suggest that you have to create a lib directory.

You don’t need to name your sub-directory lib. You can name it anything provided you put an __init__.py into it.

You can do that by entering the following command in a linux shell:

$ touch anything/__init__.py 

So now you have this structure:

$ ls anything/
__init__.py
mylib.py

$ ls
main.py

Then you can import mylib into main.py like this:

from anything import mylib 

mylib.myfun()

You can also import functions and classes like this:

from anything.mylib import MyClass
from anything.mylib import myfun

instance = MyClass()
result = myfun()

Any variable function or class you place inside __init__.py can also be accessed:

import anything

print(anything.myvar)

Or like this:

from anything import myvar

print(myvar)

回答 4

您的lib目录是否包含__init__.py文件?

Python用于__init__.py确定目录是否为模块。

Does your lib directory contain a __init__.py file?

Python uses __init__.py to determine if a directory is a module.


回答 5

尝试import .lib.BoxTime。有关更多信息,请参阅PEP 328中的相对导入。

Try import .lib.BoxTime. For more information read about relative import in PEP 328.


回答 6

我这样做基本上涵盖了所有情况(确保您__init__.py在relative / path / to / your / lib / folder中):

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()


示例:
您在项目文件夹中:

/root/myproject/app.py

您在另一个项目文件夹中:

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

您要使用/root/anotherproject/utils.py并调用其中的foo函数。

因此,您在app.py中编写:

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils

utils.foo()

I do this which basically covers all cases (make sure you have __init__.py in relative/path/to/your/lib/folder):

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/relative/path/to/your/lib/folder")
import someFileNameWhichIsInTheFolder
...
somefile.foo()


Example:
You have in your project folder:

/root/myproject/app.py

You have in another project folder:

/root/anotherproject/utils.py
/root/anotherproject/__init__.py

You want to use /root/anotherproject/utils.py and call foo function which is in it.

So you write in app.py:

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../anotherproject")
import utils

utils.foo()

回答 7

__init__.py在子目录/ lib中创建一个空文件 。并在主代码的开头添加

from __future__ import absolute_import 

然后

import lib.BoxTime as BT
...
BT.bt_function()

或更好

from lib.BoxTime import bt_function
...
bt_function()

Create an empty file __init__.py in subdirectory /lib. And add at the begin of main code

from __future__ import absolute_import 

then

import lib.BoxTime as BT
...
BT.bt_function()

or better

from lib.BoxTime import bt_function
...
bt_function()

回答 8

只是这些答案的补充。

如果要从所有子目录导入所有文件,可以将其添加到文件的根目录。

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

然后,您可以简单地从子目录中导入文件,就像这些文件位于当前目录中一样。

工作实例

如果我的项目中有以下目录及其子目录…

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
   ├── d.py
   └── e.py
├── subdirectory_b
   └── f.py
├── subdirectory_c
   └── g.py
└── subdirectory_d
    └── h.py

我可以将以下代码放入a.py文件中

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

# And then you can import files just as if these files are inside the current directory

import b
import c
import d
import e
import f
import g
import h

换句话说,此代码将抽象出文件来自哪个目录。

Just an addition to these answers.

If you want to import all files from all subdirectories, you can add this to the root of your file.

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

And then you can simply import files from the subdirectories just as if these files are inside the current directory.

Working example

If I have the following directory with subdirectories in my project…

.
├── a.py
├── b.py
├── c.py
├── subdirectory_a
│   ├── d.py
│   └── e.py
├── subdirectory_b
│   └── f.py
├── subdirectory_c
│   └── g.py
└── subdirectory_d
    └── h.py

I can put the following code inside my a.py file

import sys, os
sys.path.extend([f'./{name}' for name in os.listdir(".") if os.path.isdir(name)])

# And then you can import files just as if these files are inside the current directory

import b
import c
import d
import e
import f
import g
import h

In other words, this code will abstract from which directory the file is coming from.


回答 9

/project/tester.py

/project/lib/BoxTime.py

下一__init__.py行创建空白文件,直到找到文件

/project/lib/somefolder/BoxTime.py

#lib-需求有两个项目__init__.py,一个名为somefolder的目录 #somefolder有两个项目boxtime.py__init__.py

/project/tester.py

/project/lib/BoxTime.py

create blank file __init__.py down the line till you reach the file

/project/lib/somefolder/BoxTime.py

#lib — needs has two items one __init__.py and a directory named somefolder #somefolder has two items boxtime.py and __init__.py


回答 10

尝试这个:

from lib import BoxTime

try this:

from lib import BoxTime


正确缩进Python多行字符串

问题:正确缩进Python多行字符串

函数中Python多行字符串的正确缩进是什么?

    def method():
        string = """line one
line two
line three"""

要么

    def method():
        string = """line one
        line two
        line three"""

或者是其他东西?

在第一个示例中,将字符串挂在函数外部看起来有些奇怪。

What is the proper indentation for Python multiline strings within a function?

    def method():
        string = """line one
line two
line three"""

or

    def method():
        string = """line one
        line two
        line three"""

or something else?

It looks kind of weird to have the string hanging outside the function in the first example.


回答 0

您可能想与 """

def foo():
    string = """line one
             line two
             line three"""

由于换行符和空格包含在字符串本身中,因此您必须对其进行后处理。如果您不想这样做,并且文本很多,则可能需要将其分别存储在文本文件中。如果文本文件不能很好地适合您的应用程序,并且您不想进行后处理,那么我可能会选择

def foo():
    string = ("this is an "
              "implicitly joined "
              "string")

如果要对多行字符串进行后处理以修剪掉不需要的部分,则应考虑PEP 257中textwrap介绍的对文档字符串进行后处理的模块或技术:

def trim(docstring):
    if not docstring:
        return ''
    # Convert tabs to spaces (following the normal Python rules)
    # and split into a list of lines:
    lines = docstring.expandtabs().splitlines()
    # Determine minimum indentation (first line doesn't count):
    indent = sys.maxint
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    # Remove indentation (first line is special):
    trimmed = [lines[0].strip()]
    if indent < sys.maxint:
        for line in lines[1:]:
            trimmed.append(line[indent:].rstrip())
    # Strip off trailing and leading blank lines:
    while trimmed and not trimmed[-1]:
        trimmed.pop()
    while trimmed and not trimmed[0]:
        trimmed.pop(0)
    # Return a single string:
    return '\n'.join(trimmed)

You probably want to line up with the """

def foo():
    string = """line one
             line two
             line three"""

Since the newlines and spaces are included in the string itself, you will have to postprocess it. If you don’t want to do that and you have a whole lot of text, you might want to store it separately in a text file. If a text file does not work well for your application and you don’t want to postprocess, I’d probably go with

def foo():
    string = ("this is an "
              "implicitly joined "
              "string")

If you want to postprocess a multiline string to trim out the parts you don’t need, you should consider the textwrap module or the technique for postprocessing docstrings presented in PEP 257:

def trim(docstring):
    if not docstring:
        return ''
    # Convert tabs to spaces (following the normal Python rules)
    # and split into a list of lines:
    lines = docstring.expandtabs().splitlines()
    # Determine minimum indentation (first line doesn't count):
    indent = sys.maxint
    for line in lines[1:]:
        stripped = line.lstrip()
        if stripped:
            indent = min(indent, len(line) - len(stripped))
    # Remove indentation (first line is special):
    trimmed = [lines[0].strip()]
    if indent < sys.maxint:
        for line in lines[1:]:
            trimmed.append(line[indent:].rstrip())
    # Strip off trailing and leading blank lines:
    while trimmed and not trimmed[-1]:
        trimmed.pop()
    while trimmed and not trimmed[0]:
        trimmed.pop(0)
    # Return a single string:
    return '\n'.join(trimmed)

回答 1

textwrap.dedent功能允许在源代码中正确的缩进开始,然后在使用前从文本中删除它。

正如其他一些人所指出的那样,这是对文字的一个额外的函数调用。在决定将这些文字放在代码中的位置时,请考虑到这一点。

import textwrap

def frobnicate(param):
    """ Frobnicate the scrognate param.

        The Weebly-Ruckford algorithm is employed to frobnicate
        the scrognate to within an inch of its life.

        """
    prepare_the_comfy_chair(param)
    log_message = textwrap.dedent("""\
            Prepare to frobnicate:
            Here it comes...
                Any moment now.
            And: Frobnicate!""")
    weebly(param, log_message)
    ruckford(param)

\日志消息文字中的结尾是为了确保换行符不在文字中;这样,文字不以空白行开头,而是以下一个完整行开头。

from的返回值textwrap.dedent是输入字符串,在字符串的每一行上都删除所有常见的前导空格。因此,上面的log_message值将是:

Prepare to frobnicate:
Here it comes...
    Any moment now.
And: Frobnicate!

The textwrap.dedent function allows one to start with correct indentation in the source, and then strip it from the text before use.

The trade-off, as noted by some others, is that this is an extra function call on the literal; take this into account when deciding where to place these literals in your code.

import textwrap

def frobnicate(param):
    """ Frobnicate the scrognate param.

        The Weebly-Ruckford algorithm is employed to frobnicate
        the scrognate to within an inch of its life.

        """
    prepare_the_comfy_chair(param)
    log_message = textwrap.dedent("""\
            Prepare to frobnicate:
            Here it comes...
                Any moment now.
            And: Frobnicate!""")
    weebly(param, log_message)
    ruckford(param)

The trailing \ in the log message literal is to ensure that line break isn’t in the literal; that way, the literal doesn’t start with a blank line, and instead starts with the next full line.

The return value from textwrap.dedent is the input string with all common leading whitespace indentation removed on each line of the string. So the above log_message value will be:

Prepare to frobnicate:
Here it comes...
    Any moment now.
And: Frobnicate!

回答 2

inspect.cleandoc像这样使用:

def method():
    string = inspect.cleandoc("""
        line one
        line two
        line three""")

相对缩进将保持预期。正如评论下面,如果你想保持使用前空行,textwrap.dedent。但是,这样也可以保持第一行。

注意:优良作法是在代码的相关上下文下缩进逻辑代码块以阐明结构。例如,属于变量的多行字符串string

Use inspect.cleandoc like so:

def method():
    string = inspect.cleandoc("""
        line one
        line two
        line three""")

Relative indentation will be maintained as expected. As commented below, if you want to keep preceding empty lines, use textwrap.dedent. However that also keeps the first line break.

Note: It’s good practice to indent logical blocks of code under its related context to clarify the structure. E.g. the multi-line string belonging to the variable string.


回答 3

以下似乎是其他答案(仅在naxa的评论的最下方提到)中缺少的一个选项:

def foo():
    string = ("line one\n"          # Add \n in the string
              "line two"  "\n"      # Add "\n" after the string
              "line three\n")

这将允许正确对齐,隐式连接行并仍保持行移位,这对我来说还是我仍然要使用多行字符串的原因之一。

它不需要任何后处理,但是您需要\n在要结束行的任何给定位置手动添加。内联或后接一个单独的字符串。后者更容易复制粘贴。

One option which seems to missing from the other answers (only mentioned deep down in a comment by naxa) is the following:

def foo():
    string = ("line one\n"          # Add \n in the string
              "line two"  "\n"      # Add "\n" after the string
              "line three\n")

This will allow proper aligning, join the lines implicitly, and still keep the line shift which, for me, is one of the reasons why I would like to use multiline strings anyway.

It doesn’t require any postprocessing, but you need to manually add the \n at any given place that you want the line to end. Either inline or as a separate string after. The latter is easier to copy-paste in.


回答 4

一些更多的选择。在启用pylab的Ipython中,dedent已经在命名空间中。我检查了,它来自matplotlib。或者可以将其导入:

from matplotlib.cbook import dedent

在文档中它指出它比等效的textwrap更快,在我的ipython测试中,它的确比我的快速测试平均快3倍。它还具有丢弃任何前导空白行的好处,这使您可以灵活地构造字符串:

"""
line 1 of string
line 2 of string
"""

"""\
line 1 of string
line 2 of string
"""

"""line 1 of string
line 2 of string
"""

在这三个示例上使用matplotlib dedent将产生相同的明智结果。textwrap dedent函数在第一个示例中将有一个前导空白行。

明显的缺点是textwrap在标准库中,而matplotlib是外部模块。

这里有一些折衷… dedent函数使您的代码在定义字符串的地方更具可读性,但是需要稍后进行处理才能以可用格式获取字符串。在文档字符串中,很明显应该使用正确的缩进,因为文档字符串的大多数用法都会进行所需的处理。

当我的代码中需要一个非长字符串时,我发现以下公认的丑陋代码,在其中让长字符串脱离了封闭的缩进。肯定在“美丽比丑陋更好”上失败了,但是有人会说它比坚决的选择更简单,更明确。

def example():
    long_string = '''\
Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip.\
'''
    return long_string

print example()

Some more options. In Ipython with pylab enabled, dedent is already in the namespace. I checked and it is from matplotlib. Or it can be imported with:

from matplotlib.cbook import dedent

In documentation it states that it is faster than the textwrap equivalent one and in my tests in ipython it is indeed 3 times faster on average with my quick tests. It also has the benefit that it discards any leading blank lines this allows you to be flexible in how you construct the string:

"""
line 1 of string
line 2 of string
"""

"""\
line 1 of string
line 2 of string
"""

"""line 1 of string
line 2 of string
"""

Using the matplotlib dedent on these three examples will give the same sensible result. The textwrap dedent function will have a leading blank line with 1st example.

Obvious disadvantage is that textwrap is in standard library while matplotlib is external module.

Some tradeoffs here… the dedent functions make your code more readable where the strings get defined, but require processing later to get the string in usable format. In docstrings it is obvious that you should use correct indentation as most uses of the docstring will do the required processing.

When I need a non long string in my code I find the following admittedly ugly code where I let the long string drop out of the enclosing indentation. Definitely fails on “Beautiful is better than ugly.”, but one could argue that it is simpler and more explicit than the dedent alternative.

def example():
    long_string = '''\
Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip.\
'''
    return long_string

print example()

回答 5

如果您想要一个快速简便的解决方案并避免输入换行符,则可以选择一个列表,例如:

def func(*args, **kwargs):
    string = '\n'.join([
        'first line of very long string and',
        'second line of the same long thing and',
        'third line of ...',
        'and so on...',
        ])
    print(string)
    return

If you want a quick&easy solution and save yourself from typing newlines, you could opt for a list instead, e.g.:

def func(*args, **kwargs):
    string = '\n'.join([
        'first line of very long string and',
        'second line of the same long thing and',
        'third line of ...',
        'and so on...',
        ])
    print(string)
    return

回答 6

我更喜欢

    def method():
        string = \
"""\
line one
line two
line three\
"""

要么

    def method():
        string = """\
line one
line two
line three\
"""

I prefer

    def method():
        string = \
"""\
line one
line two
line three\
"""

or

    def method():
        string = """\
line one
line two
line three\
"""

回答 7

我的两分钱,逃离行尾以获取缩进:

def foo():
    return "{}\n"\
           "freq: {}\n"\
           "temp: {}\n".format( time, freq, temp )

My two cents, escape the end of line to get the indents:

def foo():
    return "{}\n"\
           "freq: {}\n"\
           "temp: {}\n".format( time, freq, temp )

回答 8

我来这里是为了寻找一种简单的1-衬板,以去除/校正打印时文档字符串的标识级别而又不会使其看起来不整洁,例如,通过使其在脚本内“挂在函数外部”。

我最终要做的是:

import string
def myfunction():

    """
    line 1 of docstring
    line 2 of docstring
    line 3 of docstring"""

print str(string.replace(myfunction.__doc__,'\n\t','\n'))[1:] 

显然,如果要缩进空格(例如4)而不是Tab键,请改用如下代码:

print str(string.replace(myfunction.__doc__,'\n    ','\n'))[1:]

而且,如果您希望文档字符串看起来像这样,则无需删除第一个字符:

    """line 1 of docstring
    line 2 of docstring
    line 3 of docstring"""

print string.replace(myfunction.__doc__,'\n\t','\n') 

I came here looking for a simple 1-liner to remove/correct the identation level of the docstring for printing, without making it look untidy, for example by making it “hang outside the function” within the script.

Here’s what I ended up doing:

import string
def myfunction():

    """
    line 1 of docstring
    line 2 of docstring
    line 3 of docstring"""

print str(string.replace(myfunction.__doc__,'\n\t','\n'))[1:] 

Obviously, if you’re indenting with spaces (e.g. 4) rather than the tab key use something like this instead:

print str(string.replace(myfunction.__doc__,'\n    ','\n'))[1:]

And you don’t need to remove the first character if you like your docstrings to look like this instead:

    """line 1 of docstring
    line 2 of docstring
    line 3 of docstring"""

print string.replace(myfunction.__doc__,'\n\t','\n') 

回答 9

第一种选择是好的-包括缩进。它是python样式-提供代码的可读性。

要正确显示它:

print string.lstrip()

The first option is the good one – with indentation included. It is in python style – provides readability for the code.

To display it properly:

print string.lstrip()

回答 10

这取决于您希望文本如何显示。如果您希望所有内容都左对齐,则可以按照第一个代码段的格式对其进行格式化,也可以遍历所有空间的左行进行迭代。

It depends on how you want the text to display. If you want it all to be left-aligned then either format it as in the first snippet or iterate through the lines left-trimming all the space.


回答 11

对于字符串,您可以在处理字符串之后。对于文档字符串,您需要对函数进行后处理。这是一个仍然可读的解决方案。

class Lstrip(object):
    def __rsub__(self, other):
        import re
        return re.sub('^\n', '', re.sub('\n$', '', re.sub('\n\s+', '\n', other)))

msg = '''
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
      veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
      commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
      velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
      cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
      est laborum.
      ''' - Lstrip()

print msg

def lstrip_docstring(func):
    func.__doc__ = func.__doc__ - Lstrip()
    return func

@lstrip_docstring
def foo():
    '''
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
    veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
    commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
    velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
    cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
    est laborum.
    '''
    pass


print foo.__doc__

For strings you can just after process the string. For docstrings you need to after process the function instead. Here is a solution for both that is still readable.

class Lstrip(object):
    def __rsub__(self, other):
        import re
        return re.sub('^\n', '', re.sub('\n$', '', re.sub('\n\s+', '\n', other)))

msg = '''
      Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
      veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
      commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
      velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
      cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
      est laborum.
      ''' - Lstrip()

print msg

def lstrip_docstring(func):
    func.__doc__ = func.__doc__ - Lstrip()
    return func

@lstrip_docstring
def foo():
    '''
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
    veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
    commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
    velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
    cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
    est laborum.
    '''
    pass


print foo.__doc__

回答 12

我遇到类似的问题,使用多行代码使代码变得难以理解,我想到了类似

print("""aaaa
"""   """bbb
""")

是的,一开始看起来可能很糟糕,但是嵌入式语法非常复杂,并且在末尾添加一些内容(例如’\ n“’)不是解决方案

I’m having a similar issue, code got really unreadable using multilines, I came out with something like

print("""aaaa
"""   """bbb
""")

yes, at beginning could look terrible but the embedded syntax was quite complex and adding something at the end (like ‘\n”‘) was not a solution


回答 13

您可以使用此函数trim_indent

import re


def trim_indent(s: str):
    s = re.sub(r'^\n+', '', s)
    s = re.sub(r'\n+$', '', s)
    spaces = re.findall(r'^ +', s, flags=re.MULTILINE)
    if len(spaces) > 0 and len(re.findall(r'^[^\s]', s, flags=re.MULTILINE)) == 0:
        s = re.sub(r'^%s' % (min(spaces)), '', s, flags=re.MULTILINE)
    return s


print(trim_indent("""


        line one
            line two
                line three
            line two
        line one


"""))

结果:

"""
line one
    line two
        line three
    line two
line one
"""

You can use this function trim_indent.

import re


def trim_indent(s: str):
    s = re.sub(r'^\n+', '', s)
    s = re.sub(r'\n+$', '', s)
    spaces = re.findall(r'^ +', s, flags=re.MULTILINE)
    if len(spaces) > 0 and len(re.findall(r'^[^\s]', s, flags=re.MULTILINE)) == 0:
        s = re.sub(r'^%s' % (min(spaces)), '', s, flags=re.MULTILINE)
    return s


print(trim_indent("""


        line one
            line two
                line three
            line two
        line one


"""))

Result:

"""
line one
    line two
        line three
    line two
line one
"""

按多个属性对列表进行排序?

问题:按多个属性对列表进行排序?

我有一个清单清单:

[[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]

如果我想按一个元素(例如,高/短元素)排序,则可以通过进行s = sorted(s, key = itemgetter(1))

如果我想同时根据高/短和颜色进行排序,我可以进行两次排序,每个元素一次,但是有一种更快的方法吗?

I have a list of lists:

[[12, 'tall', 'blue', 1],
[2, 'short', 'red', 9],
[4, 'tall', 'blue', 13]]

If I wanted to sort by one element, say the tall/short element, I could do it via s = sorted(s, key = itemgetter(1)).

If I wanted to sort by both tall/short and colour, I could do the sort twice, once for each element, but is there a quicker way?


回答 0

键可以是返回元组的函数:

s = sorted(s, key = lambda x: (x[1], x[2]))

或者,您可以使用来达到相同的效果itemgetter(速度更快,并且避免了Python函数调用):

import operator
s = sorted(s, key = operator.itemgetter(1, 2))

并请注意,您可以在此处使用sort而不是使用sorted,然后重新分配:

s.sort(key = operator.itemgetter(1, 2))

A key can be a function that returns a tuple:

s = sorted(s, key = lambda x: (x[1], x[2]))

Or you can achieve the same using itemgetter (which is faster and avoids a Python function call):

import operator
s = sorted(s, key = operator.itemgetter(1, 2))

And notice that here you can use sort instead of using sorted and then reassigning:

s.sort(key = operator.itemgetter(1, 2))

回答 1

我不确定这是否是最pythonic的方法……我有一个元组列表,需要按降序对整数值进行排序,然后按字母顺序对第二个进行排序。这需要反转整数排序,而不是字母排序。这是我的解决方案:(在一次考试中,我什至不知道您可以“嵌套”排序功能)

a = [('Al', 2),('Bill', 1),('Carol', 2), ('Abel', 3), ('Zeke', 2), ('Chris', 1)]  
b = sorted(sorted(a, key = lambda x : x[0]), key = lambda x : x[1], reverse = True)  
print(b)  
[('Abel', 3), ('Al', 2), ('Carol', 2), ('Zeke', 2), ('Bill', 1), ('Chris', 1)]

I’m not sure if this is the most pythonic method … I had a list of tuples that needed sorting 1st by descending integer values and 2nd alphabetically. This required reversing the integer sort but not the alphabetical sort. Here was my solution: (on the fly in an exam btw, I was not even aware you could ‘nest’ sorted functions)

a = [('Al', 2),('Bill', 1),('Carol', 2), ('Abel', 3), ('Zeke', 2), ('Chris', 1)]  
b = sorted(sorted(a, key = lambda x : x[0]), key = lambda x : x[1], reverse = True)  
print(b)  
[('Abel', 3), ('Al', 2), ('Carol', 2), ('Zeke', 2), ('Bill', 1), ('Chris', 1)]

回答 2

看来您可以使用list而不是tuple。我认为,当您获取属性而不是列表/元组的“魔术索引”时,这变得尤为重要。

在我的情况下,我想按类的多个属性进行排序,其中传入的键是字符串。我需要在不同的地方进行不同的排序,并且我希望为与客户进行交互的父类提供一个通用的默认排序。只需在真正需要时覆盖“排序键”,而且还可以将它们存储为类可以共享的列表

所以首先我定义了一个辅助方法

def attr_sort(self, attrs=['someAttributeString']:
  '''helper to sort by the attributes named by strings of attrs in order'''
  return lambda k: [ getattr(k, attr) for attr in attrs ]

然后使用它

# would defined elsewhere but showing here for consiseness
self.SortListA = ['attrA', 'attrB']
self.SortListB = ['attrC', 'attrA']
records = .... #list of my objects to sort
records.sort(key=self.attr_sort(attrs=self.SortListA))
# perhaps later nearby or in another function
more_records = .... #another list
more_records.sort(key=self.attr_sort(attrs=self.SortListB))

这将使用生成的lambda函数对列表进行排序object.attrA,然后object.attrB假定object具有与提供的字符串名称相对应的getter。到object.attrC那时,第二种情况将得到解决object.attrA

这还允许您潜在地暴露向外的排序选择,以供使用者,单元测试共享,或者让他们告诉您他们希望如何对api中的某些操作进行排序,而只需给您一个列表,而不是将它们耦合到您的后端实现。

It appears you could use a list instead of a tuple. This becomes more important I think when you are grabbing attributes instead of ‘magic indexes’ of a list/tuple.

In my case I wanted to sort by multiple attributes of a class, where the incoming keys were strings. I needed different sorting in different places, and I wanted a common default sort for the parent class that clients were interacting with; only having to override the ‘sorting keys’ when I really ‘needed to’, but also in a way that I could store them as lists that the class could share

So first I defined a helper method

def attr_sort(self, attrs=['someAttributeString']:
  '''helper to sort by the attributes named by strings of attrs in order'''
  return lambda k: [ getattr(k, attr) for attr in attrs ]

then to use it

# would defined elsewhere but showing here for consiseness
self.SortListA = ['attrA', 'attrB']
self.SortListB = ['attrC', 'attrA']
records = .... #list of my objects to sort
records.sort(key=self.attr_sort(attrs=self.SortListA))
# perhaps later nearby or in another function
more_records = .... #another list
more_records.sort(key=self.attr_sort(attrs=self.SortListB))

This will use the generated lambda function sort the list by object.attrA and then object.attrB assuming object has a getter corresponding to the string names provided. And the second case would sort by object.attrC then object.attrA.

This also allows you to potentially expose outward sorting choices to be shared alike by a consumer, a unit test, or for them to perhaps tell you how they want sorting done for some operation in your api by only have to give you a list and not coupling them to your back end implementation.


回答 3

几年迟到了,但我想这两个排序2个标准使用reverse=True。如果其他人想知道如何做,则可以将您的条件(函数)括在括号中:

s = sorted(my_list, key=lambda i: ( criteria_1(i), criteria_2(i) ), reverse=True)

Several years late to the party but I want to both sort on 2 criteria and use reverse=True. In case someone else wants to know how, you can wrap your criteria (functions) in parenthesis:

s = sorted(my_list, key=lambda i: ( criteria_1(i), criteria_2(i) ), reverse=True)

回答 4

这是一种方法:您基本上是重写您的排序函数以获取一个排序函数列表,每个排序函数都会比较您要测试的属性,在每次排序测试中,您都会查看并查看cmp函数是否返回非零返回值如果是这样,则中断并发送返回值。您可以通过调用Lambda列表功能的Lambda来调用它。

它的优点是它可以单次通过数据,而不像其他方法那样通过以前的排序。另一件事是,它排序到位,而排序似乎可以复制。

我用它编写了一个等级函数,该函数对每个对象在一个组中并具有得分函数的类列表进行排名,但是您可以添加任何属性列表。请注意类似unlambda的内容,尽管会使用lambda来调用setter。等级部分不适用于列表数组,但排序可以。

#First, here's  a pure list version
my_sortLambdaLst = [lambda x,y:cmp(x[0], y[0]), lambda x,y:cmp(x[1], y[1])]
def multi_attribute_sort(x,y):
    r = 0
    for l in my_sortLambdaLst:
        r = l(x,y)
        if r!=0: return r #keep looping till you see a difference
    return r

Lst = [(4, 2.0), (4, 0.01), (4, 0.9), (4, 0.999),(4, 0.2), (1, 2.0), (1, 0.01), (1, 0.9), (1, 0.999), (1, 0.2) ]
Lst.sort(lambda x,y:multi_attribute_sort(x,y)) #The Lambda of the Lambda
for rec in Lst: print str(rec)

这是一种对对象列表进行排名的方法

class probe:
    def __init__(self, group, score):
        self.group = group
        self.score = score
        self.rank =-1
    def set_rank(self, r):
        self.rank = r
    def __str__(self):
        return '\t'.join([str(self.group), str(self.score), str(self.rank)]) 


def RankLst(inLst, group_lambda= lambda x:x.group, sortLambdaLst = [lambda x,y:cmp(x.group, y.group), lambda x,y:cmp(x.score, y.score)], SetRank_Lambda = lambda x, rank:x.set_rank(rank)):
    #Inner function is the only way (I could think of) to pass the sortLambdaLst into a sort function
    def multi_attribute_sort(x,y):
        r = 0
        for l in sortLambdaLst:
            r = l(x,y)
            if r!=0: return r #keep looping till you see a difference
        return r

    inLst.sort(lambda x,y:multi_attribute_sort(x,y))
    #Now Rank your probes
    rank = 0
    last_group = group_lambda(inLst[0])
    for i in range(len(inLst)):
        rec = inLst[i]
        group = group_lambda(rec)
        if last_group == group: 
            rank+=1
        else:
            rank=1
            last_group = group
        SetRank_Lambda(inLst[i], rank) #This is pure evil!! The lambda purists are gnashing their teeth

Lst = [probe(4, 2.0), probe(4, 0.01), probe(4, 0.9), probe(4, 0.999), probe(4, 0.2), probe(1, 2.0), probe(1, 0.01), probe(1, 0.9), probe(1, 0.999), probe(1, 0.2) ]

RankLst(Lst, group_lambda= lambda x:x.group, sortLambdaLst = [lambda x,y:cmp(x.group, y.group), lambda x,y:cmp(x.score, y.score)], SetRank_Lambda = lambda x, rank:x.set_rank(rank))
print '\t'.join(['group', 'score', 'rank']) 
for r in Lst: print r

Here’s one way: You basically re-write your sort function to take a list of sort functions, each sort function compares the attributes you want to test, on each sort test, you look and see if the cmp function returns a non-zero return if so break and send the return value. You call it by calling a Lambda of a function of a list of Lambdas.

Its advantage is that it does single pass through the data not a sort of a previous sort as other methods do. Another thing is that it sorts in place, whereas sorted seems to make a copy.

I used it to write a rank function, that ranks a list of classes where each object is in a group and has a score function, but you can add any list of attributes. Note the un-lambda-like, though hackish use of a lambda to call a setter. The rank part won’t work for an array of lists, but the sort will.

#First, here's  a pure list version
my_sortLambdaLst = [lambda x,y:cmp(x[0], y[0]), lambda x,y:cmp(x[1], y[1])]
def multi_attribute_sort(x,y):
    r = 0
    for l in my_sortLambdaLst:
        r = l(x,y)
        if r!=0: return r #keep looping till you see a difference
    return r

Lst = [(4, 2.0), (4, 0.01), (4, 0.9), (4, 0.999),(4, 0.2), (1, 2.0), (1, 0.01), (1, 0.9), (1, 0.999), (1, 0.2) ]
Lst.sort(lambda x,y:multi_attribute_sort(x,y)) #The Lambda of the Lambda
for rec in Lst: print str(rec)

Here’s a way to rank a list of objects

class probe:
    def __init__(self, group, score):
        self.group = group
        self.score = score
        self.rank =-1
    def set_rank(self, r):
        self.rank = r
    def __str__(self):
        return '\t'.join([str(self.group), str(self.score), str(self.rank)]) 


def RankLst(inLst, group_lambda= lambda x:x.group, sortLambdaLst = [lambda x,y:cmp(x.group, y.group), lambda x,y:cmp(x.score, y.score)], SetRank_Lambda = lambda x, rank:x.set_rank(rank)):
    #Inner function is the only way (I could think of) to pass the sortLambdaLst into a sort function
    def multi_attribute_sort(x,y):
        r = 0
        for l in sortLambdaLst:
            r = l(x,y)
            if r!=0: return r #keep looping till you see a difference
        return r

    inLst.sort(lambda x,y:multi_attribute_sort(x,y))
    #Now Rank your probes
    rank = 0
    last_group = group_lambda(inLst[0])
    for i in range(len(inLst)):
        rec = inLst[i]
        group = group_lambda(rec)
        if last_group == group: 
            rank+=1
        else:
            rank=1
            last_group = group
        SetRank_Lambda(inLst[i], rank) #This is pure evil!! The lambda purists are gnashing their teeth

Lst = [probe(4, 2.0), probe(4, 0.01), probe(4, 0.9), probe(4, 0.999), probe(4, 0.2), probe(1, 2.0), probe(1, 0.01), probe(1, 0.9), probe(1, 0.999), probe(1, 0.2) ]

RankLst(Lst, group_lambda= lambda x:x.group, sortLambdaLst = [lambda x,y:cmp(x.group, y.group), lambda x,y:cmp(x.score, y.score)], SetRank_Lambda = lambda x, rank:x.set_rank(rank))
print '\t'.join(['group', 'score', 'rank']) 
for r in Lst: print r

如何将熊猫数据框的索引转换为列?

问题:如何将熊猫数据框的索引转换为列?

这似乎很明显,但是我似乎无法弄清楚如何将数据帧的索引转换为列?

例如:

df=
        gi       ptt_loc
 0  384444683      593  
 1  384444684      594 
 2  384444686      596  

至,

df=
    index1    gi       ptt_loc
 0  0     384444683      593  
 1  1     384444684      594 
 2  2     384444686      596  

This seems rather obvious, but I can’t seem to figure out how to convert an index of data frame to a column?

For example:

df=
        gi       ptt_loc
 0  384444683      593  
 1  384444684      594 
 2  384444686      596  

To,

df=
    index1    gi       ptt_loc
 0  0     384444683      593  
 1  1     384444684      594 
 2  2     384444686      596  

回答 0

要么:

df['index1'] = df.index

.reset_index

df.reset_index(level=0, inplace=True)

因此,如果您有一个3级索引的多索引框架,例如:

>>> df
                       val
tick       tag obs        
2016-02-26 C   2    0.0139
2016-02-27 A   2    0.5577
2016-02-28 C   6    0.0303

并且要将索引中的第1级(tick)和第3级(obs)转换为列,您可以执行以下操作:

>>> df.reset_index(level=['tick', 'obs'])
          tick  obs     val
tag                        
C   2016-02-26    2  0.0139
A   2016-02-27    2  0.5577
C   2016-02-28    6  0.0303

either:

df['index1'] = df.index

or, .reset_index:

df.reset_index(level=0, inplace=True)

so, if you have a multi-index frame with 3 levels of index, like:

>>> df
                       val
tick       tag obs        
2016-02-26 C   2    0.0139
2016-02-27 A   2    0.5577
2016-02-28 C   6    0.0303

and you want to convert the 1st (tick) and 3rd (obs) levels in the index into columns, you would do:

>>> df.reset_index(level=['tick', 'obs'])
          tick  obs     val
tag                        
C   2016-02-26    2  0.0139
A   2016-02-27    2  0.5577
C   2016-02-28    6  0.0303

回答 1

对于MultiIndex,您可以使用以下方法提取其子索引

df['si_name'] = R.index.get_level_values('si_name') 

si_name索引的名称在哪里。

For MultiIndex you can extract its subindex using

df['si_name'] = R.index.get_level_values('si_name') 

where si_name is the name of the subindex.


回答 2

为了更加清楚,让我们看一下索引中具有两个级别的DataFrame(一个MultiIndex)。

index = pd.MultiIndex.from_product([['TX', 'FL', 'CA'], 
                                    ['North', 'South']], 
                                   names=['State', 'Direction'])

df = pd.DataFrame(index=index, 
                  data=np.random.randint(0, 10, (6,4)), 
                  columns=list('abcd'))

在此处输入图片说明

reset_index使用默认参数调用的方法将所有索引级别转换为列,并使用简单RangeIndex的新索引。

df.reset_index()

在此处输入图片说明

使用level参数控制将哪些索引级别转换为列。如果可能,请使用更明确的级别名称。如果没有级别名称,则可以通过其整数位置来引用每个级别,整数位置从外部开始为0。您可以在此处使用标量值或要重置的所有索引的列表。

df.reset_index(level='State') # same as df.reset_index(level=0)

在此处输入图片说明

在极少数情况下,您想要保留索引并将索引转换为列,可以执行以下操作:

# for a single level
df.assign(State=df.index.get_level_values('State'))

# for all levels
df.assign(**df.index.to_frame())

To provide a bit more clarity, let’s look at a DataFrame with two levels in its index (a MultiIndex).

index = pd.MultiIndex.from_product([['TX', 'FL', 'CA'], 
                                    ['North', 'South']], 
                                   names=['State', 'Direction'])

df = pd.DataFrame(index=index, 
                  data=np.random.randint(0, 10, (6,4)), 
                  columns=list('abcd'))

enter image description here

The reset_index method, called with the default parameters, converts all index levels to columns and uses a simple RangeIndex as new index.

df.reset_index()

enter image description here

Use the level parameter to control which index levels are converted into columns. If possible, use the level name, which is more explicit. If there are no level names, you can refer to each level by its integer location, which begin at 0 from the outside. You can use a scalar value here or a list of all the indexes you would like to reset.

df.reset_index(level='State') # same as df.reset_index(level=0)

enter image description here

In the rare event that you want to preserve the index and turn the index into a column, you can do the following:

# for a single level
df.assign(State=df.index.get_level_values('State'))

# for all levels
df.assign(**df.index.to_frame())

回答 3

rename_axis + reset_index

您可以先将索引重命名为所需的标签,然后提升为一系列:

df = df.rename_axis('index1').reset_index()

print(df)

   index1         gi  ptt_loc
0       0  384444683      593
1       1  384444684      594
2       2  384444686      596

这也适用于MultiIndex数据框:

print(df)
#                        val
# tick       tag obs        
# 2016-02-26 C   2    0.0139
# 2016-02-27 A   2    0.5577
# 2016-02-28 C   6    0.0303

df = df.rename_axis(['index1', 'index2', 'index3']).reset_index()

print(df)

       index1 index2  index3     val
0  2016-02-26      C       2  0.0139
1  2016-02-27      A       2  0.5577
2  2016-02-28      C       6  0.0303

rename_axis + reset_index

You can first rename your index to a desired label, then elevate to a series:

df = df.rename_axis('index1').reset_index()

print(df)

   index1         gi  ptt_loc
0       0  384444683      593
1       1  384444684      594
2       2  384444686      596

This works also for MultiIndex dataframes:

print(df)
#                        val
# tick       tag obs        
# 2016-02-26 C   2    0.0139
# 2016-02-27 A   2    0.5577
# 2016-02-28 C   6    0.0303

df = df.rename_axis(['index1', 'index2', 'index3']).reset_index()

print(df)

       index1 index2  index3     val
0  2016-02-26      C       2  0.0139
1  2016-02-27      A       2  0.5577
2  2016-02-28      C       6  0.0303

回答 4

如果要使用该reset_index方法并保留现有索引,则应使用:

df.reset_index().set_index('index', drop=False)

或更改它的位置:

df.reset_index(inplace=True)
df.set_index('index', drop=False, inplace=True)

例如:

print(df)
          gi  ptt_loc
0  384444683      593
4  384444684      594
9  384444686      596

print(df.reset_index())
   index         gi  ptt_loc
0      0  384444683      593
1      4  384444684      594
2      9  384444686      596

print(df.reset_index().set_index('index', drop=False))
       index         gi  ptt_loc
index
0          0  384444683      593
4          4  384444684      594
9          9  384444686      596

如果要摆脱索引标签,可以执行以下操作:

df2 = df.reset_index().set_index('index', drop=False)
df2.index.name = None
print(df2)
   index         gi  ptt_loc
0      0  384444683      593
4      4  384444684      594
9      9  384444686      596

If you want to use the reset_index method and also preserve your existing index you should use:

df.reset_index().set_index('index', drop=False)

or to change it in place:

df.reset_index(inplace=True)
df.set_index('index', drop=False, inplace=True)

For example:

print(df)
          gi  ptt_loc
0  384444683      593
4  384444684      594
9  384444686      596

print(df.reset_index())
   index         gi  ptt_loc
0      0  384444683      593
1      4  384444684      594
2      9  384444686      596

print(df.reset_index().set_index('index', drop=False))
       index         gi  ptt_loc
index
0          0  384444683      593
4          4  384444684      594
9          9  384444686      596

And if you want to get rid of the index label you can do:

df2 = df.reset_index().set_index('index', drop=False)
df2.index.name = None
print(df2)
   index         gi  ptt_loc
0      0  384444683      593
4      4  384444684      594
9      9  384444686      596

回答 5

df1 = pd.DataFrame({"gi":[232,66,34,43],"ptt":[342,56,662,123]})
p = df1.index.values
df1.insert( 0, column="new",value = p)
df1

    new     gi     ptt
0    0      232    342
1    1      66     56 
2    2      34     662
3    3      43     123
df1 = pd.DataFrame({"gi":[232,66,34,43],"ptt":[342,56,662,123]})
p = df1.index.values
df1.insert( 0, column="new",value = p)
df1

    new     gi     ptt
0    0      232    342
1    1      66     56 
2    2      34     662
3    3      43     123

回答 6

一种简单的方法是使用reset_index()方法。对于数据帧df,请使用以下代码:

df.reset_index(inplace=True)

这样,索引将成为一列,并且通过使用inplace作为True,这将成为永久更改。

A very simple way of doing this is to use reset_index() method.For a data frame df use the code below:

df.reset_index(inplace=True)

This way, the index will become a column, and by using inplace as True,this become permanent change.


删除文件的大多数pythonic方法

问题:删除文件的大多数pythonic方法

我要删除该文件(filename如果存在)。说的合适吗

if os.path.exists(filename):
    os.remove(filename)

有没有更好的办法?单行方式?

I want to delete the file filename if it exists. Is it proper to say

if os.path.exists(filename):
    os.remove(filename)

Is there a better way? A one-line way?


回答 0

一种更pythonic的方式是:

try:
    os.remove(filename)
except OSError:
    pass

尽管这需要花费更多的行,并且看起来很丑陋,但可以避免不必要的调用 os.path.exists()并遵循过度使用异常的python约定。

可能值得编写一个函数为您执行此操作:

import os, errno

def silentremove(filename):
    try:
        os.remove(filename)
    except OSError as e: # this would be "except OSError, e:" before Python 2.6
        if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
            raise # re-raise exception if a different error occurred

A more pythonic way would be:

try:
    os.remove(filename)
except OSError:
    pass

Although this takes even more lines and looks very ugly, it avoids the unnecessary call to os.path.exists() and follows the python convention of overusing exceptions.

It may be worthwhile to write a function to do this for you:

import os, errno

def silentremove(filename):
    try:
        os.remove(filename)
    except OSError as e: # this would be "except OSError, e:" before Python 2.6
        if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
            raise # re-raise exception if a different error occurred

回答 1

我更喜欢抑制异常,而不是检查文件的存在,以避免TOCTTOU错误。Matt的答案就是一个很好的例子,但是我们可以在Python 3下使用contextlib.suppress()以下方法稍微简化一下:

import contextlib

with contextlib.suppress(FileNotFoundError):
    os.remove(filename)

如果filename是一个pathlib.Path对象而不是字符串,我们可以调用其.unlink()方法而不是使用os.remove()。以我的经验,Path对象比字符串更有用。

由于此答案中的所有内容都是Python 3专有的,因此它提供了另一个升级理由。

I prefer to suppress an exception rather than checking for the file’s existence, to avoid a TOCTTOU bug. Matt’s answer is a good example of this, but we can simplify it slightly under Python 3, using contextlib.suppress():

import contextlib

with contextlib.suppress(FileNotFoundError):
    os.remove(filename)

If filename is a pathlib.Path object instead of a string, we can call its .unlink() method instead of using os.remove(). In my experience, Path objects are more useful than strings for filesystem manipulation.

Since everything in this answer is exclusive to Python 3, it provides yet another reason to upgrade.


回答 2

os.path.exists返回True文件夹和文件。考虑使用os.path.isfile来检查文件是否存在。

os.path.exists returns True for folders as well as files. Consider using os.path.isfile to check for whether the file exists instead.


回答 3

本着安迪·琼斯(Andy Jones)的回答精神,如何进行真正的三元运算:

os.remove(fn) if os.path.exists(fn) else None

In the spirit of Andy Jones’ answer, how about an authentic ternary operation:

os.remove(fn) if os.path.exists(fn) else None

回答 4

知道文件是否存在并删除的另一种方法是使用模块glob。

from glob import glob
import os

for filename in glob("*.csv"):
    os.remove(filename)

Glob查找所有可以使用* nix通配符选择模式的文件,并循环列表。

Another way to know if the file (or files) exists, and to remove it, is using the module glob.

from glob import glob
import os

for filename in glob("*.csv"):
    os.remove(filename)

Glob finds all the files that could select the pattern with a *nix wildcard, and loops the list.


回答 5

从Python 3.8开始,请使用missing_ok=Truepathlib.Path.unlinkdocs此处

from pathlib import Path

my_file = Path("./dir1/dir2/file.txt")

# Python 3.8+
my_file.unlink(missing_ok=True)

# Python 3.7 and earlier
if my_file.exists():
    my_file.unlink()

As of Python 3.8, use missing_ok=True and pathlib.Path.unlink (docs here)

from pathlib import Path

my_file = Path("./dir1/dir2/file.txt")

# Python 3.8+
my_file.unlink(missing_ok=True)

# Python 3.7 and earlier
if my_file.exists():
    my_file.unlink()

回答 6

Matt的答案是较老的Python和Kevin的正确答案的正确答案,答案是较新的的正确答案。

如果您不想复制的功能silentremove,则此功能在path.py中显示remove_p

from path import Path
Path(filename).remove_p()

Matt’s answer is the right one for older Pythons and Kevin’s the right answer for newer ones.

If you wish not to copy the function for silentremove, this functionality is exposed in path.py as remove_p:

from path import Path
Path(filename).remove_p()

回答 7

if os.path.exists(filename): os.remove(filename)

是单线的。

你们中的许多人可能会不同意(可能是出于考虑将三元体系建议使用为“丑陋”的理由)的想法,但这引出了一个问题,即当人们习惯将丑陋标准称为“非丑陋”时,我们是否应该听取他们的意见。

if os.path.exists(filename): os.remove(filename)

is a one-liner.

Many of you may disagree – possibly for reasons like considering the proposed use of ternaries “ugly” – but this begs the question of whether we should listen to people used to ugly standards when they call something non-standard “ugly”.


回答 8

在Python 3.4或更高版本中,pythonic方式为:

import os
from contextlib import suppress

with suppress(OSError):
    os.remove(filename)

In Python 3.4 or later version, the pythonic way would be:

import os
from contextlib import suppress

with suppress(OSError):
    os.remove(filename)

回答 9

像这样吗 利用短路评估。如果文件不存在,则整个条件不能为真,因此python不会麻烦评估第二部分。

os.path.exists("gogogo.php") and os.remove("gogogo.php")

Something like this? Takes advantage of short-circuit evaluation. If the file does not exist, the whole conditional cannot be true, so python will not bother evaluation the second part.

os.path.exists("gogogo.php") and os.remove("gogogo.php")

回答 10

亲吻提供:

def remove_if_exists(filename):
  if os.path.exists(filename):
    os.remove(filename)

然后:

remove_if_exists("my.file")

A KISS offering:

def remove_if_exists(filename):
  if os.path.exists(filename):
    os.remove(filename)

And then:

remove_if_exists("my.file")

回答 11

这是另一个解决方案:

if os.path.isfile(os.path.join(path, filename)):
    os.remove(os.path.join(path, filename))

This is another solution:

if os.path.isfile(os.path.join(path, filename)):
    os.remove(os.path.join(path, filename))

回答 12

带有您自己的消息的另一种解决方案。

import os

try:
    os.remove(filename)
except:
    print("Not able to delete the file %s" % filename)

Another solution with your own message in exception.

import os

try:
    os.remove(filename)
except:
    print("Not able to delete the file %s" % filename)

回答 13

我曾经用过rm,它可以强制删除不存在的文件,并可以将其--preserve-root作为选项rm

--preserve-root
              do not remove `/' (default)

rm --help | grep "force"
  -f, --force           ignore nonexistent files and arguments, never prompt

我们也可以使用safe-rmsudo apt-get install safe-rm

Safe-rm是一种安全工具,旨在通过使用包装程序替换/ bin / rm来防止重要文件的意外删除,该包装程序将对给定的参数与永不删除的可配置文件和目录黑名单进行检查。

首先,我检查文件夹/文件路径是否存在。这将防止设置变量fileToRemove /folderToRemove to the string-r /`。


import os, subprocess

fileToRemove = '/home/user/fileName';
if os.path.isfile(fileToRemove):
   subprocess.run(['rm', '-f', '--preserve-root', fileToRemove]
   subprocess.run(['safe-rm', '-f', fileToRemove]

I have used rm which can force to delete nonexistent files with --preserve-root as an option to rm.

--preserve-root
              do not remove `/' (default)

rm --help | grep "force"
  -f, --force           ignore nonexistent files and arguments, never prompt

We can also use safe-rm (sudo apt-get install safe-rm)

Safe-rm is a safety tool intended to prevent the accidental deletion of important files by replacing /bin/rm with a wrapper, which checks the given arguments against a configurable blacklist of files and directories that should never be removed.

First I check whether folder/file path exist or not. This will prevent setting variable fileToRemove/folderToRemoveto the string-r /`.


import os, subprocess

fileToRemove = '/home/user/fileName';
if os.path.isfile(fileToRemove):
   subprocess.run(['rm', '-f', '--preserve-root', fileToRemove]
   subprocess.run(['safe-rm', '-f', fileToRemove]

用Python创建新字典

问题:用Python创建新字典

我想用Python建立字典。但是,我看到的所有示例都是从列表中实例化字典等。..

如何在Python中创建一个新的空字典?

I want to build a dictionary in Python. However, all the examples that I see are instantiating a dictionary from a list, etc . ..

How do I create a new empty dictionary in Python?


回答 0

dict无参数调用

new_dict = dict()

或简单地写

new_dict = {}

Call dict with no parameters

new_dict = dict()

or simply write

new_dict = {}

回答 1

你可以这样做

x = {}
x['a'] = 1

You can do this

x = {}
x['a'] = 1

回答 2

知道如何编写预设字典对了解也很有帮助:

cmap =  {'US':'USA','GB':'Great Britain'}

# Explicitly:
# -----------
def cxlate(country):
    try:
        ret = cmap[country]
    except KeyError:
        ret = '?'
    return ret

present = 'US' # this one is in the dict
missing = 'RU' # this one is not

print cxlate(present) # == USA
print cxlate(missing) # == ?

# or, much more simply as suggested below:

print cmap.get(present,'?') # == USA
print cmap.get(missing,'?') # == ?

# with country codes, you might prefer to return the original on failure:

print cmap.get(present,present) # == USA
print cmap.get(missing,missing) # == RU

Knowing how to write a preset dictionary is useful to know as well:

cmap =  {'US':'USA','GB':'Great Britain'}

# Explicitly:
# -----------
def cxlate(country):
    try:
        ret = cmap[country]
    except KeyError:
        ret = '?'
    return ret

present = 'US' # this one is in the dict
missing = 'RU' # this one is not

print cxlate(present) # == USA
print cxlate(missing) # == ?

# or, much more simply as suggested below:

print cmap.get(present,'?') # == USA
print cmap.get(missing,'?') # == ?

# with country codes, you might prefer to return the original on failure:

print cmap.get(present,present) # == USA
print cmap.get(missing,missing) # == RU

回答 3

>>> dict(a=2,b=4)
{'a': 2, 'b': 4}

将值添加到python字典中。

>>> dict(a=2,b=4)
{'a': 2, 'b': 4}

Will add the value in the python dictionary.


回答 4

d = dict()

要么

d = {}

要么

import types
d = types.DictType.__new__(types.DictType, (), {})
d = dict()

or

d = {}

or

import types
d = types.DictType.__new__(types.DictType, (), {})

回答 5

因此,有两种创建字典的方法:

  1. my_dict = dict()

  2. my_dict = {}

但是,在这两个选项{}中,比dict()加上其可读性更有效。 在这里检查

So there 2 ways to create a dict :

  1. my_dict = dict()

  2. my_dict = {}

But out of these two options {} is efficient than dict() plus its readable. CHECK HERE


回答 6

>>> dict.fromkeys(['a','b','c'],[1,2,3])


{'a': [1, 2, 3], 'b': [1, 2, 3], 'c': [1, 2, 3]}
>>> dict.fromkeys(['a','b','c'],[1,2,3])


{'a': [1, 2, 3], 'b': [1, 2, 3], 'c': [1, 2, 3]}

Python错误“ ImportError:未命名模块”

问题:Python错误“ ImportError:未命名模块”

Python安装在本地目录中。

我的目录树如下所示:

(local directory)/site-packages/toolkit/interface.py

我的代码在这里:

(local directory)/site-packages/toolkit/examples/mountain.py

要运行该示例,我编写python mountain.py,并且在代码中有:

from toolkit.interface import interface

我得到错误:

Traceback (most recent call last):
  File "mountain.py", line 28, in ?
    from toolkit.interface import interface
ImportError: No module named toolkit.interface

我已经检查过了sys.path,这里有目录/site-packages。另外,我__init__.py.bin在toolkit文件夹中有该文件,以向Python指示这是一个软件包。我__init__.py.bin在示例目录中也有一个。

我不知道为什么Python在时找不到文件sys.path。有任何想法吗?可以是权限问题吗?我需要执行许可吗?

Python is installed in a local directory.

My directory tree looks like this:

(local directory)/site-packages/toolkit/interface.py

My code is in here:

(local directory)/site-packages/toolkit/examples/mountain.py

To run the example, I write python mountain.py, and in the code I have:

from toolkit.interface import interface

And I get the error:

Traceback (most recent call last):
  File "mountain.py", line 28, in ?
    from toolkit.interface import interface
ImportError: No module named toolkit.interface

I have already checked sys.path and there I have the directory /site-packages. Also, I have the file __init__.py.bin in the toolkit folder to indicate to Python that this is a package. I also have a __init__.py.bin in the examples directory.

I do not know why Python cannot find the file when it is in sys.path. Any ideas? Can it be a permissions problem? Do I need some execution permission?


回答 0

根据您对orip帖子的评论,我想这是发生了什么:

  1. __init__.py在Windows上进行了编辑。
  2. Windows编辑器添加了一些不可打印的内容,也许是回车符(Windows中的行尾是CR / LF;在Unix中是LF),或者是CTRL-Z(Windows文件末尾)。
  3. 您使用WinSCP将文件复制到Unix框中。
  4. WinSCP认为:“这不是基本文字;我将添加.bin扩展名以指示二进制数据。”
  5. 缺少__init__.py(现在称为__init__.py.bin)意味着python无法将工具包理解为一个包。
  6. __init__.py在适当的目录中创建,一切正常…?

Based on your comments to orip’s post, I guess this is what happened:

  1. You edited __init__.py on windows.
  2. The windows editor added something non-printing, perhaps a carriage-return (end-of-line in Windows is CR/LF; in unix it is LF only), or perhaps a CTRL-Z (windows end-of-file).
  3. You used WinSCP to copy the file to your unix box.
  4. WinSCP thought: “This has something that’s not basic text; I’ll put a .bin extension to indicate binary data.”
  5. The missing __init__.py (now called __init__.py.bin) means python doesn’t understand toolkit as a package.
  6. You create __init__.py in the appropriate directory and everything works… ?

回答 1

是否

(local directory)/site-packages/toolkit

有一个__init__.py

为了使进口步行通过你的目录中的每个目录必须有一个__init__.py文件。

Does

(local directory)/site-packages/toolkit

have a __init__.py?

To make import walk through your directories every directory must have a __init__.py file.


回答 2

我在LPTHW中进行此练习时遇到了非常相似的事情。我永远无法让Python识别出我正在从其调用的目录中有文件。但是我最终能够使它工作。我所做的以及我的建议是尝试以下操作:

(注意:从您的第一篇文章中,我假设您使用的是基于* NIX的计算机,并且正在通过命令行运行,因此此建议是针对性的。自从我运行Ubuntu以来,我就是这样做的。)

1)将目录(cd)更改为文件所在目录上方的目录。在这种情况下,您将尝试运行mountain.py文件,并尝试调用toolkit.interface.py位于单独目录中的模块。在这种情况下,您将转到包含两个文件路径的目录(或换句话说,这两个文件的路径共享的最近目录)。在这种情况下是toolkit目录。

2)在tookit目录中时,在命令行上输入以下代码行:

export PYTHONPATH=.

这会将您的PYTHONPATH设置为“。”,这基本上意味着您的PYTHONPATH现在将在您当前所在目录(甚至更重要的是,您所在目录的子目录分支)中查找所有被调用的文件。因此,它不只是看在你的当前目录,但在所有可在目录中的当前目录)。

3)在上述步骤中设置完PYTHONPATH之后,请从当前目录(该toolkit目录)运行模块。Python现在应该找到并加载您指定的模块。

希望这可以帮助。我自己对此感到非常沮丧。

I ran into something very similar when I did this exercise in LPTHW; I could never get Python to recognise that I had files in the directory I was calling from. But I was able to get it to work in the end. What I did, and what I recommend, is to try this:

(NOTE: From your initial post, I am assuming you are using an *NIX-based machine and are running things from the command line, so this advice is tailored to that. Since I run Ubuntu, this is what I did)

1) Change directory (cd) to the directory above the directory where your files are. In this case, you’re trying to run the mountain.py file, and trying to call the toolkit.interface.py module, which are in separate directories. In this case, you would go to the directory that contains paths to both those files (or in other words, the closest directory that the paths of both those files share). Which in this case is the toolkit directory.

2) When you are in the tookit directory, enter this line of code on your command line:

export PYTHONPATH=.

This sets your PYTHONPATH to “.”, which basically means that your PYTHONPATH will now look for any called files within the directory you are currently in, (and more to the point, in the sub-directory branches of the directory you are in. So it doesn’t just look in your current directory, but in all the directories that are in your current directory).

3) After you’ve set your PYTHONPATH in the step above, run your module from your current directory (the toolkit directory). Python should now find and load the modules you specified.

Hope this helps. I was quite frustrated with this myself.


回答 3

在* nix上,还要确保正确配置了PYTHONPATH,尤其是它具有以下格式:

 .:/usr/local/lib/python

(请注意.:开头,以便它也可以在当前目录中搜索。)

它也可能在其他位置,具体取决于版本:

 .:/usr/lib/python
 .:/usr/lib/python2.6
 .:/usr/lib/python2.7 and etc.

On *nix, also make sure that PYTHONPATH is configured correctly, especially that it has this format:

 .:/usr/local/lib/python

(Mind the .: at the beginning, so that it can search on the current directory, too.)

It may also be in other locations, depending on the version:

 .:/usr/lib/python
 .:/usr/lib/python2.6
 .:/usr/lib/python2.7 and etc.

回答 4

我解决了自己的问题,并将总结出错误的地方和解决方案:

该文件需要完全调用__init__.py。如果扩展名不同(例如在我的情况下),.py.bin则Python无法在目录中移动,因此找不到模块。要编辑文件,您需要使用Linux编辑器,例如vinano。如果您使用Windows编辑器,则会写一些隐藏的字符。

影响它的另一个问题是,我的根目录安装了另一个Python版本,因此,如果有人正在使用python的本地安装,请确保运行程序的Python安装是本地Python。要检查这一点,只需执行which python,然后查看可执行文件是否在您的本地目录中。如果不是,请更改路径,但请确保本地Python目录位于另一个Python目录之前。

I solved my own problem, and I will write a summary of the things that were wrong and the solution:

The file needs to be called exactly __init__.py. If the extension is different such as in my case .py.bin then Python cannot move through the directories and then it cannot find the modules. To edit the files you need to use a Linux editor, such as vi or nano. If you use a Windows editor this will write some hidden characters.

Another problem that was affecting it was that I had another Python version installed by the root, so if someone is working with a local installation of python, be sure that the Python installation that is running the programs is the local Python. To check this, just do which python, and see if the executable is the one that is in your local directory. If not, change the path, but be sure that the local Python directory is before than the other Python.


回答 5

一个简单的解决方案是使用来安装模块,python -m pip install <library-name>而不是pip install <library-name> 在管理员限制的情况下使用sudo

an easy solution is to install the module using python -m pip install <library-name> instead of pip install <library-name> you may use sudo in case of admin restrictions


回答 6

要将目录标记为包,您需要一个名为的文件__init__.py,这有帮助吗?

To mark a directory as a package you need a file named __init__.py, does this help?


回答 7

使用PyCharm(属于JetBrains套件的一部分),您需要将脚本目录定义为Source:
Right Click > Mark Directory as > Sources Root

Using PyCharm (part of the JetBrains suite) you need to define your script directory as Source:
Right Click > Mark Directory as > Sources Root


回答 8

您正在阅读此答案,表明您__init__.py来对地方了,已经安装了所有依赖项,并且仍在获取ImportError

我遇到了类似的问题,除了我的程序在使用PyCharm运行时可以正常运行,但是当我从终端运行时出现上述错误。进一步挖掘之后,我发现PYTHONPATH该项目目录中没有该条目。因此,我将PYTHONPATH每个Import语句设置为在PyCharm上有效,但不能在terminal上使用

export PYTHONPATH=$PYTHONPATH:`pwd`  (OR your project root directory)

使用sys.pathas 的另一种方法是:

import sys
sys.path.insert(0,'<project directory>') OR
sys.path.append('<project directory>')

您可以根据要搜索项目的顺序使用插入/追加。

You are reading this answer says that your __init__.py is in the right place, you have installed all the dependencies and you are still getting the ImportError.

I was facing a similar issue except that my program would run fine when ran using PyCharm but the above error when I would run it from the terminal. After digging further, I found out that PYTHONPATH didn’t have the entry for the project directory. So, I set PYTHONPATH per Import statement works on PyCharm but not from terminal:

export PYTHONPATH=$PYTHONPATH:`pwd`  (OR your project root directory)

There’s another way to do this using sys.path as:

import sys
sys.path.insert(0,'<project directory>') OR
sys.path.append('<project directory>')

You can use insert/append based on the order in which you want your project to be searched.


回答 9

对我来说,那真是愚蠢。我使用来安装该库,pip3 install但正在运行程序python program.py而不是python3 program.py

For me, it was something really stupid. I installed the library using pip3 install but was running my program as python program.py as opposed to python3 program.py.


回答 10

对。您需要包含该__init__.py文件的目录,该文件是用于初始化程序包的文件。在这里,看看这个

__init__.py文件是使Python将目录视为包含包所必需的;这样做是为了防止具有通用名称的目录(例如字符串)无意间隐藏了稍后在模块搜索路径中出现的有效模块。在最简单的情况下,__init__.py可以只是一个空文件,但它也可以为该程序包执行初始化代码或设置__all__变量,如后所述。

Yup. You need the directory to contain the __init__.py file, which is the file that initializes the package. Here, have a look at this.

The __init__.py files are required to make Python treat the directories as containing packages; this is done to prevent directories with a common name, such as string, from unintentionally hiding valid modules that occur later on the module search path. In the simplest case, __init__.py can just be an empty file, but it can also execute initialization code for the package or set the __all__ variable, described later.


回答 11

  1. 您必须在与要导入文件相同的目录中拥有文件__ init__.py。
  2. 您不能尝试从PYTHONPATH上配置的2个文件夹中导入具有相同名称的文件。

例如:/ etc / environment

PYTHONPATH = $ PYTHONPATH:/ opt /文件夹1:/ opt /文件夹2

/ opt / folder1 / foo

/ opt / folder2 / foo

并且,如果您尝试导入foo文件,python将不知道您要哪个。

从foo import … >>> importerror:没有名为foo的模块

  1. You must have the file __ init__.py in the same directory where it’s the file that you are importing.
  2. You can not try to import a file that has the same name and be a file from 2 folders configured on the PYTHONPATH.

eg: /etc/environment

PYTHONPATH=$PYTHONPATH:/opt/folder1:/opt/folder2

/opt/folder1/foo

/opt/folder2/foo

And, if you are trying to import foo file, python will not know which one you want.

from foo import … >>> importerror: no module named foo


回答 12

我的两分钱:

在此处输入图片说明

吐:

Traceback (most recent call last):
      File "bash\bash.py", line 454, in main
        import bosh
      File "Wrye Bash Launcher.pyw", line 63, in load_module
        mod = imp.load_source(fullname,filename+ext,fp)
      File "bash\bosh.py", line 69, in <module>
        from game.oblivion.RecordGroups import MobWorlds, MobDials, MobICells, \
    ImportError: No module named RecordGroups

这让我很困惑-遍历各种帖子,暗示了丑陋的syspath hacks(如您所见,我__init__.py在那里)。好吧,事实证明game / oblivion.py和game / oblivion混淆了python,并吐出了相当无用的“没有名为RecordGroups的模块”。我对解决此问题和/或记录此(相同名称)行为的链接感兴趣->编辑(2017.01.24)-看看如果我具有相同名称的模块和软件包怎么办?有趣的是,通常程序包具有优先权,但显然我们的启动程序违反了此规则。

编辑(2015.01.17):我没有提到我们使用此处剖析的自定义启动器

My two cents:

enter image description here

Spit:

Traceback (most recent call last):
      File "bash\bash.py", line 454, in main
        import bosh
      File "Wrye Bash Launcher.pyw", line 63, in load_module
        mod = imp.load_source(fullname,filename+ext,fp)
      File "bash\bosh.py", line 69, in <module>
        from game.oblivion.RecordGroups import MobWorlds, MobDials, MobICells, \
    ImportError: No module named RecordGroups

This confused the hell out of me – went through posts and posts suggesting ugly syspath hacks (as you see my __init__.py were all there). Well turns out that game/oblivion.py and game/oblivion was confusing python which spit out the rather unhelpful “No module named RecordGroups”. I’d be interested in a workaround and/or links documenting this (same name) behavior -> EDIT (2017.01.24) – have a look at What If I Have a Module and a Package With The Same Name? Interestingly normally packages take precedence but apparently our launcher violates this.

EDIT (2015.01.17): I did not mention we use a custom launcher dissected here.


回答 13

Linux:导入的模块位于/usr/local/lib/python2.7/dist-packages中

如果您使用的是用C语言编译的模块,请不要忘了在之后对.so文件进行chmod修改sudo setup.py install

sudo chmod 755 /usr/local/lib/python2.7/dist-packages/*.so

Linux: Imported modules are located in /usr/local/lib/python2.7/dist-packages

If you’re using a module compiled in C, don’t forget to chmod the .so file after sudo setup.py install.

sudo chmod 755 /usr/local/lib/python2.7/dist-packages/*.so

回答 14

就我而言,问题是我链接到debug pythonboost::Python,它要求扩展名是FooLib_d.pyd,而不仅仅是FooLib.pyd; 重命名文件或更新CMakeLists.txt属性可修复该错误。

In my case, the problem was I was linking to debug python & boost::Python, which requires that the extension be FooLib_d.pyd, not just FooLib.pyd; renaming the file or updating CMakeLists.txt properties fixed the error.


回答 15

如果您尝试了上面提供的所有方法但都失败了,则也许您的模块内置模块具有相同的名称。或者,文件夹中存在的同名sys.path模块比模块具有更高的优先级。

要调试,请说出您的from foo.bar import baz抱怨ImportError: No module named bar。更改为import foo; print foo,将显示的路径foo。是您所期望的吗?

如果不是,请重命名foo或使用绝对导入

If you have tried all methods provided above but failed, maybe your module has the same name as a built-in module. Or, a module with the same name existing in a folder that has a high priority in sys.path than your module’s.

To debug, say your from foo.bar import baz complaints ImportError: No module named bar. Changing to import foo; print foo, which will show the path of foo. Is it what you expect?

If not, Either rename foo or use absolute imports.


回答 16

我的问题是,__init__.py实际上需要添加其父目录时,我将带有文件的目录添加到了PYTHONPATH中。

My problem was that I added the directory with the __init__.py file to PYTHONPATH, when actually I needed to add its parent directory.


回答 17

对于所有仍然有此问题的人。我相信Pycharm与进口商品混淆了。对我来说,当我写“从命名空间导入某物”时,前一行用红色下划线标出,表示有错误,但可以。但是,“从.namespace导入某些内容”不会带有下划线,但也无法正常工作。

尝试

try:
    from namespace import something 
except NameError:
    from .namespace import something

To all those who still have this issue. I believe Pycharm gets confused with imports. For me, when i write ‘from namespace import something’, the previous line gets underlined in red, signaling that there is an error, but works. However ”from .namespace import something’ doesn’t get underlined, but also doesn’t work.

Try

try:
    from namespace import something 
except NameError:
    from .namespace import something

回答 18

通过编写修复了我的问题print (sys.path),发现尽管进行了全新安装,python仍在使用过期的软件包。删除这些使python自动使用正确的软件包。

Fixed my issue by writing print (sys.path) and found out that python was using out of date packages despite a clean install. Deleting these made python automatically use the correct packages.


回答 19

就我而言,因为我正在使用PyCharm和PyCharm在项目文件夹中为每个项目创建一个“ venv”,但这只是python的一个迷你环境。尽管您已经在Python中安装了所需的库,但是在您的自定义项目“ venv”中,该库不可用。这是PyCharm中发生“导入错误:没有名为xxxxxx的模块”的真正原因。要解决此问题,必须通过以下步骤将库添加到项目自定义环境中:

  • 在PyCharm中,从菜单“文件”->“设置”
  • 在设置对话框中,项目:XXXProject->项目解释器
  • 点击“添加”按钮,它将显示“可用包”对话框
  • 搜索您的库,单击“安装软件包”
  • 然后,所有需要的软件包将安装在项目自定义“ venv”文件夹中。

设置对话框

请享用。

In my case, because I’m using PyCharm and PyCharm create a ‘venv’ for every project in project folder, but it is only a mini env of python. Although you have installed the libraries you need in Python, but in your custom project ‘venv’, it is not available. This is the real reason of ‘ImportError: No module named xxxxxx’ occurred in PyCharm. To resolve this issue, you must add libraries to your project custom env by these steps:

  • In PyCharm, from menu ‘File’->Settings
  • In Settings dialog, Project: XXXProject->Project Interpreter
  • Click “Add” button, it will show you ‘Available Packages’ dialog
  • Search your library, click ‘Install Package’
  • Then, all you needed package will be installed in you project custom ‘venv’ folder.

Settings dialog

Enjoy.


回答 20

在经历了同样的问题后,我发现我的解决方案是pyc从项目中删除所有文件,似乎这些缓存的文件以某种方式导致了此错误。

我发现最简单的方法是在Windows资源管理器中导航到我的项目文件夹并搜索*.pyc,然后选择所有(Ctrl+ A)并删除它们(Ctrl+ X)。

可能我可以通过删除特定pyc文件来解决问题,但我从未尝试过

After just suffering the same issue I found my resolution was to delete all pyc files from my project, it seems like these cached files were somehow causing this error.

Easiest way I found to do this was to navigate to my project folder in Windows explorer and searching for *.pyc, then selecting all (Ctrl+A) and deleting them (Ctrl+X).

Its possible I could have resolved my issues by just deleting the specific pyc file but I never tried this


回答 21

我遇到了同样的问题:Import error。此外,该库已正确安装了100%。问题的根源是在我的PC 3版本上安装了python(anaconda数据包)。这就是为什么没有将库安装到正确的位置的原因。之后,我只是在我的IDE PyCharm中更改为python的正确版本。

I faced the same problem: Import error. In addition the library’ve been installed 100% correctly. The source of the problem was that on my PC 3 version of python (anaconda packet) have been installed). This is why the library was installed no to the right place. After that I just changed to the proper version of python in the my IDE PyCharm.


回答 22

我有同样的错误。这是因为有人在与脚本相同的文件夹中创建了一个文件夹,该文件夹的名称与我从其他位置导入的模块冲突。它没有导入外部模块,而是查看了该文件夹内部,该文件夹显然不包含预期的模块。

I had the same error. It was caused by somebody creating a folder in the same folder as my script, the name of which conflicted with a module I was importing from elsewhere. Instead of importing the external module, it looked inside this folder which obviously didn’t contain the expected modules.


回答 23

我遇到了同样的问题(Python 2.7 Linux),我找到了解决方案,我想分享一下。就我而言,我的结构如下:

Booklet
-> __init__.py
-> Booklet.py
-> Question.py
default
-> __init_.py
-> main.py

在“ main.py”中,我尝试了以下所有组合,但均未成功:

from Booklet import Question
from Question import Question
from Booklet.Question import Question
from Booklet.Question import *
import Booklet.Question
# and many othet various combinations ...

解决方案比我想象的要简单得多。我将文件夹“ Booklet”重命名为“ booklet”,仅此而已。现在,Python可以通过在“ main.py”中使用以下代码来正常导入Question类:

from booklet.Booklet import Booklet
from booklet.Question import Question
from booklet.Question import AnotherClass

由此我可以得出结论,像“小册子”之类的包名称(文件夹)必须以小写开头,否则Python会将其与类名和文件名混淆。

显然,这不是您的问题,但是John Fouhy的回答非常好,并且该线程具有几乎所有可能导致此问题的东西。因此,这是一回事,我希望这可以对其他人有所帮助。

I had the same problem (Python 2.7 Linux), I have found the solution and i would like to share it. In my case i had the structure below:

Booklet
-> __init__.py
-> Booklet.py
-> Question.py
default
-> __init_.py
-> main.py

In ‘main.py’ I had tried unsuccessfully all the combinations bellow:

from Booklet import Question
from Question import Question
from Booklet.Question import Question
from Booklet.Question import *
import Booklet.Question
# and many othet various combinations ...

The solution was much more simple than I thought. I renamed the folder “Booklet” into “booklet” and that’s it. Now Python can import the class Question normally by using in ‘main.py’ the code:

from booklet.Booklet import Booklet
from booklet.Question import Question
from booklet.Question import AnotherClass

From this I can conclude that Package-Names (folders) like ‘booklet’ must start from lower-case, else Python confuses it with Class names and Filenames.

Apparently, this was not your problem, but John Fouhy’s answer is very good and this thread has almost anything that can cause this issue. So, this is one more thing and I hope that maybe this could help others.


回答 24

就我而言,我要包含package.egg文件夹的路径,而不是其下面的实际软件包。我将软件包复制到顶层,并且可以正常工作。

In my case I was including the path to package.egg folder rather than the actual package underneath. I copied the package to top level and it worked.


回答 25

这对我有用:__init__.py在父文件夹中创建文件(在您的情况下,在site-packages文件夹中)。并像这样导入:

from site-packages.toolkit.interface import interface

希望它对您也有用!

This worked for me: Created __init__.py file inside parent folder (in your case, inside site-packages folder). And imported like this:

from site-packages.toolkit.interface import interface

Hope it will be useful for you as well !


回答 26

在linux服务器上尝试 dos2unix script_name

pyc使用命令删除所有(如果有的话)文件find . -name '*.pyc' -delete

如果您在Windows上处理脚本,请重新运行

In linux server try dos2unix script_name

(remove all (if there is any) pyc files with command find . -name '*.pyc' -delete)

and re run in the case if you worked on script on windows


回答 27

就我而言,我是sys.path.insert()用来导入本地模块的,并且是module not found从另一个库中获取的。我不得不把sys.path.insert()进口的商品放在下面module not found。我想最好的做法是放在sys.path.insert()进口的底部。

In my case, I was using sys.path.insert() to import a local module and was getting module not found from a different library. I had to put sys.path.insert() below the imports that reported module not found. I guess the best practice is to put sys.path.insert() at the bottom of your imports.