在Python中打高尔夫球的技巧


248

您使用Python打高尔夫球有哪些一般技巧?我正在寻找可以应用于代码高尔夫球问题的想法,并且这些想法至少也特定于Python(例如,“删除注释”不是答案)。

请为每个答案发布一个提示。


27
哦,我可以看到每种语言都会出现这样的一系列问题……
R. Martinho Fernandes

4
@Marthinho我同意。刚开始相当于C ++。只要我们看不到在许多这类问题中重新发布相同的答案,我就认为这不是一件坏事。
marcog 2011年

50
喜欢这个问题,但我必须不断告诉自己“这只是出于娱乐目的,而不是针对生产代码”
Greg Guida

2
这个问题不应该是社区Wiki帖子吗?
dorukayhan '16

3
@dorukayhan Nope; 这是一个有效的代码高尔夫 技巧问题,要求您提供有关出于CG目的而缩短python代码的技巧。这样的问题对于该站点是完全有效的,并且这些标签都没有明确指出应该对问题进行CW处理,与SO不同,SO需要对CG挑战进行CW处理。另外,编写一个好的答案并找到这样的技巧总是值得的,如果问题是社区Wiki(rep),则该东西将被取消。
暴民埃里克

Answers:


152

使用a=b=c=0代替a,b,c=0,0,0

使用a,b,c='123'代替a,b,c='1','2','3'


2
总的来说,这是个不错的技巧:)

28
请注意,这对于定义将要就地修改的可变对象不一定有效。a = b = [1]实际上不同于a = [1]; b = [1]
isaacg 2014年

6
关于第一个技巧的有趣之处在于它也可以在Java中工作。
贾斯汀

1
@Justin是的,但仅适用于原始类型
HyperNeutrino

11
但是切勿使用a = b = c = []或任何对象实例化,因为所有变量都将指向同一实例。那可能不是您想要的。
PhE

146

条件句可能很长。在某些情况下,您可以将替换为简单的条件(a,b)[condition]。如果condition为true,则b返回。

相比

if a<b:return a
else:return b

对此

return(b,a)[a<b]

37
这些并不完全相同。第一个仅计算返回的表达式,而第二个始终对两个表达式均求值。这些那些做短路:a if a<b else ba<b and a or b
海产

3
(lambda(): b, lambda(): a)[a < b]()使自己的短路与lambda表达式
明堂

3
@marinus,它们不相等:只要考虑P and A or B给定的A即可bool(A)=False。但是(P and [A] or [B])[0]会做的。有关参考,请参见diveintopython.net/power_of_introspection/and_or.html
kgadek

6
Lambda比条件表达式长得多。
user2357112 2014年

18
@ user2357112但是当您使用它们时,它们使您看起来更加酷。:]
Chase Ries 2014年

117

我曾经做过的一件很棒的事是:

if 3 > a > 1 < b < 5: foo()

代替:

if a > 1 and b > 1 and 3 > a and 5 > b: foo()

Python的比较运算符令人震惊。


使用所有东西在Python 2中都是可比的,您还可以通过and这种方式避免使用运算符。例如,如果abcd是整数,

if a<b and c>d:foo()

可以缩短一个字符以:

if a<b<[]>c>d:foo()

这使用每个列表大于任何整数。

如果cd是列表,情况会更好:

if a<b<c>d:foo()

22
当然,如果这确实打过高尔夫球,那就应该是3>a>1<b<5
Rafe Kettler

4
爱对称。让我想起了旧的Perl高尔夫技巧,它可以找到$ a和$ b的最小值:[$a => $b]->[$b <= $a]:)
Simon Whitaker

请注意,第二个示例(无列表)也可以使用if(a<b)+(c>d):foo()
WorldSEnder,2014年

6
+应该是*。一个or+
WorldSEnder


103

如果您反复使用内置函数,则使用不同的参数时,为其重新命名可能会更节省空间:

r=range
for x in r(10):
 for y in r(100):print x,y

6
不过实际上并没有保存任何字节。
user2357112 2014年

4
r = range,其他两个r为9个字符;两次使用范围是10个字符。在此示例中,这并不是一个巨大的节省,但是只需再多使用一次范围,即可节省大量费用。
Frank Frank

13
@Frank附加换行符是另一个字符。
L3viathan

2
实际上,两个重复太少了,无法保存长度为5的函数名。您需要:长度2:6次,长度3:4次,长度4或5:3次,长度> = 6:2次。又名(length-1)*(reps-1)> 4。
与Orjan约翰森

请注意,这适用于具有一流功能的所有语言。
bfontaine

94

有时,您的Python代码要求您具有2个缩进级别。显而易见的事情是为每个缩进级别使用一个和两个空格。

但是,Python 2认为制表符和空格字符是不同的缩进级别。

这意味着第一个缩进级别可以是一个空格,第二个缩进级别可以是一个制表符。

例如:

if 1:
 if 1:
\tpass

\t制表符在哪里。


1
太酷了,我从未想过这个!
JulesOlléon2011年

97
这在python3中失败:您不能再混合空格和制表符(对codegolf来说是一件坏事,但在所有其他情况下是一件好事)。
巴库里

1
在python 3.4中,这似乎工作正常。
trichoplax

3
@trichoplax,在python 3.4.3中,我得到了TabError: inconsistent use of tabs and spaces in indentation.
ceilingcat '16

供参考,一个制表符值得8个空格。
暴民埃里克(Erik the Outgolfer)

87

使用字符串替换并exec处理lambda在代码中经常重复的长关键字。

a=lambda b:lambda c:lambda d:lambda e:lambda f:0   # 48 bytes  (plain)
exec"a=`b:`c:`d:`e:`f:0".replace('`','lambda ')    # 47 bytes  (replace)
exec"a=%sb:%sc:%sd:%se:%sf:0"%(('lambda ',)*5)     # 46 bytes  (%)

目标字符串通常'lambda '是7字节长。假设您的代码段包含n的出现'lambda ',并且为s字节长。然后:

  • plain选项的长度为s字节。
  • replace选项的长度为s - 6n + 29字节。
  • %选项的长度为s - 5n + 22 + len(str(n))字节。

从为这三个选项保存下来字节plain图中,我们可以看到:

  • 对于n <5的 lambda,最好不要做任何花哨的事情。
  • 对于n = 5,写入可exec"..."%(('lambda ',)*5)节省2个字节,这是您的最佳选择。
  • 对于n> 5,写作exec"...".replace('`','lambda ')是您的最佳选择。

对于其他情况,您可以索引下表:

          1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 (occurences)
       +---------------------------------------------------------
     3 |  -  -  -  -  -  -  -  -  -  -  -  -  -  -  r  r  r  r  r  
     4 |  -  -  -  -  -  -  -  -  -  r  r  r  r  r  r  r  r  r  r  
     5 |  -  -  -  -  -  -  -  r  r  r  r  r  r  r  r  r  r  r  r  
     6 |  -  -  -  -  -  r  r  r  r  r  r  r  r  r  r  r  r  r  r  
     7 |  -  -  -  -  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r  
     8 |  -  -  -  %  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r  
     9 |  -  -  -  %  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r  
    10 |  -  -  %  %  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r  
    11 |  -  -  %  %  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r  
    12 |  -  -  %  %  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r = replace
    13 |  -  -  %  %  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r   % = string %
    14 |  -  %  %  %  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r   - = do nothing
    15 |  -  %  %  %  %  r  r  r  r  r  r  r  r  r  r  r  r  r  r  
  (length)

例如,如果字符串lambda x,y:(长度为11)在代码中出现3次,则最好编写exec"..."%(('lambda x,y:',)*3)


4
这应该获得更多选票,这是一个非常有用的提示。
bigblind

7
这种方法非常罕见。的代价replace是巨大的。
2013年

4
但是,当它起作用时,它会很有帮助。
Undergroundmonorail

有趣的是,甚至从来没有想过!
Claudiu 2014年

我基于python在我的语言中添加了一个用于lambda的新运算符:=>仅仅是string = lambda 。例如,f=>:0将为f = lambda: 0
NoOneIsHere

78

使用扩展切片从多个字符串中选择一个字符串

>>> for x in 0,1,2:print"fbboaaorz"[x::3]
... 
foo
bar
baz

>>> for x in 0,1,2:print["foo","bar","baz"][x]
... 
foo
bar
baz

在这种布尔型两字符串的情况下,也可以写

b*"string"or"other_string"

对于

["other_string","string"][b]

与交织不同,这适用于任何长度的字符串,但如果b是表达式,则可能会有运算符优先级问题。


请注意,第一个示例的长度与for x in ("foo","bar","baz"): print x
Mateen Ulhaq

1
@MateenUlhaq,这只是如何x呈现的不同值的一个示例。打高尔夫球的部分是"fbboaaorz"[x::3]vs。["foo","bar","baz"][x]如何得出x值将是您高尔夫解决方案的另一部分。
gnibbler


69

将查找表存储为幻数

假设您要对布尔值查找表进行硬编码,例如前十二个英文数字中的哪个包含一个n

0: False
1: True
2: False
3: False
4: False
5: False
6: False
7: True
8: False
9: True
10:True
11:True
12:False

然后,您可以简洁地实现此查找表:

3714>>i&1

用所得01等于FalseTrue

这个想法是,魔数将表存储为位串bin(3714)= 0b111010000010n第-个数字(从末尾开始)对应于第nth个表项。我们n通过将数字n空间向右移一位并将最后一位乘以来访问第th个条目&1

这种存储方法非常有效。与替代品比较

n in[1,7,9,10,11]
'0111010000010'[n]>'0'

您可以让您的查找表存储可以提取的多位条目,例如

 340954054>>4*n&15

提取相关的四位块。


我们可以得到一个四位块的示例结果吗?您是否对n位块使用了规则?
JeromeJ

8
十六进制有时可能会更小。
Joonazan '16

4
这对于许多语言很有用。
Cyoce'2

1
@Joonazan十六进制是对数字越小999 999
Mateen Ulhaq

60

将两个数字循环合为一

假设您要遍历m*n网格的各个单元。代替两个嵌套for循环,一个用于行,一个列,通常使用单个循环m*n在网格的单元上进行迭代会更短。您可以提取循环内单元格的行和列。

原始代码:

for i in range(m):
 for j in range(n):
  do_stuff(i,j)

高尔夫代码:

for k in range(m*n):
  do_stuff(k/n,k%n)

实际上,您要遍历两个范围的笛卡尔积,将对编码(i,j)x=i*n+j。您已经range在循环中节省了昂贵的调用和一定程度的缩进。迭代顺序不变。

使用//而不是/如果你是指在Python 3 ij很多次,它可能会更快分配他们的价值观i=k/nj=k%n内循环。


5
这太棒了。我从未意识到这是可能的!
theonlygusti 2015年

我在JavaScript技巧中看到了这一点。在大多数语言中,这是一个非常有用的技巧。
Cyoce

7
作为参考,将其扩展到3个循环:for i in range(m*n*o): do_stuff(i/n/o,i%(n*o)/o,i%o)
mbomb007 '16

3
对于n循环:repl.it/EHwa
mbomb007 '16

在某些情况下,itertools.product比嵌套循环更简洁,尤其是在生成笛卡尔积时。a1, a2, b1, b2'ab''12'
Aaron3468 '18

54

除非以下标记以e或开头E。您可以删除数字后面的空格。

例如:

if i==4 and j==4:
    pass

成为:

if i==4and j==4:
    pass

在复杂的单行语句中使用此功能可以节省很多字符。

编辑:正如@marcog指出的那样,4or a可以使用,但是不能a or4与变量名混淆。


37
if(i,j)==(4,4):甚至更短,在这种特殊情况下if i==j==4:
狼吞虎咽2011年

3
相关:4or a作品,但没有a or4
marcog 2011年

17
0or也不起作用(0o是八进制数字的前缀)。
Nabb 2011年

5
@Nabb但这并不重要,因为0 or x它总是会返回x。最好切掉0 or
ɐɔıʇǝɥʇuʎs

5
0or可以作为较长数字的一部分。10 or x等同于10or x
trichoplax

53

对于integer n,您可以编写

  • n+1-~n
  • n-1~-n

因为位翻转~x等于-1-x。这使用相同数量的字符,但是可以间接地切开空格或为操作符优先级而忽略。

相比:

while n-1:  #Same as while n!=1 
while~-n:

c/(n-1)
c/~-n

or f(n)+1
or-~f(n) 

(n-1)/10+(n-1)%10
~-n/10+~-n%10

运算符~和一元-的优先级高于*/%,不像二进制+


11
我今天遇到的这个技巧的一种变体:-~-x相对于保存一个字节(1-x)
林恩

4
另一个有用的应用程序a+b+1可以更简洁地编写为a-~b
Strigoides

而且n-i-1就是n+~i
ruohola

51

Python 3上将可迭代对象转换为列表的一种好方法:

想象你有一些可迭代的东西,比如

i = (1,2,3,4)
i = range(4)
i = (x**2 for x in range(5))

但是您需要一个列表:

x=list(i)  #the default way
*x,=i      #using starred assignment -> 4 char fewer

从字符串中列出字符列表非常有用

s=['a','b','c','d','e']
s=list('abcde')
*s,='abcde'

1
键入*s,='abcde',然后s用segfault使我的交互式python3崩溃:(
daniero

@daniero哇。仅在交互式控制台上?听起来很奇怪。在干净的控制台上尝试或报告错误
JBernardo

1
我的Python 3.5工作正常。
NoOneIsHere

对于i =(对于x在范围(5)中的x ** 2),我得到的代码返回<生成器对象<genexpr>在0x03321690>
乔治

7
如果您要在表达式中执行此操作,则可以执行[*'abcde']
Esolanging Fruit

46

如果您实际上不需要使用值,则range(x)可以使用*运算符代替任何东西i

for i in[1]*8:pass

相对于

for i in range(8):pass

如果您需要执行两次以上操作,则可以将任何可迭代的变量赋给变量,然后将该变量乘以所需的范围:

r=1,
for i in r*8:pass
for i in r*1000:pass

注意:这通常比更长exec"pass;"*8,因此仅在无法选择时才使用此技巧。


@proudhaskeller我认为您删除的行的重点是“除了可以节省明显的字符,因为[1]*8它比短range(8),而且还可以节省空间,因为for i in[...合法for i in range...的却不是。”
地下

哦,对,我听不懂。立即修复
骄傲的haskeller 2014年

7
exec"pass;"*8明显更短。
DJMcMayhem

1
如果r=1r*8则为8,则无法迭代数字。我想你的意思是r=[1]
Artemis Fowl

1
@ArtemisFowl,不,就这样,1之后的逗号会创建一个可迭代的元组。
萨沙

43

您可以使用外星人的老笑脸来反转序列:

[1, 2, 3, 4][::-1] # => [4, 3, 2, 1]

38

扩展的可迭代拆包(“加星标的任务”,仅适用于Python 3)

最好的解释方法是通过一个示例:

>>> a,*b,c=range(5)
>>> a
0
>>> b
[1, 2, 3]
>>> c
4

我们已经看到了这样做的用途- 在Python 3中将可迭代对象转换为列表

a=list(range(10))
*a,=range(10)

这里有更多用途。

从列表中获取最后一个元素

a=L[-1]
*_,a=L

在某些情况下,这也可以用于获取要保存在parens上的第一个元素:

a=(L+[1])[0]
a,*_=L+[1]

分配一个空列表和其他变量

a=1;b=2;c=[]
a,b,*c=1,2

删除非空列表的第一个或最后一个元素

_,*L=L
*L,_=L

这些比替代项L=L[1:]和短L.pop()。结果也可以保存到其他列表中。

提示@grc


哇!我写了a=1;L=[]很多次。您可以将char保存在如此简单的内容上,这真是令人惊讶。
xnor 2014年

@xnor谢谢grc。仅使用其他一个元素,效果不佳(a,*L=1,),但它仍然节省了一个字符:)
Sp3000

别忘了,您也可以通过a,*_,b=L
Cyoce '16

36

在Python2.7中设置文字

您可以这样编写集合,S={1,2,3}这也意味着您可以使用{e}&S来检查成员资格,而不是使用e in S它来保存一个字符。


4
这也将字符保存在ifs中,因为没有空格(if{e}&S:
Artyer

1
请注意,您可以替换not in通过{e}-S与招
黑色猫头鹰凯

35

很久以来,我一直不敢想出一个简短的方法来获取整个字母。如果您在程序中使用rangeR=range值得拥有的东西,那么

[chr(i+97)for i in R(26)]

比天真短

'abcdefghijklmnopqrstuvwxyz'

,但更长的时间是单个字符。令我困扰的是,一个聪明的人需要一定的ascii值知识,最终变得比仅仅键入所有字母更加冗长。

直到我看到这个答案对我女儿的字母。我无法很好地了解编辑历史记录,无法弄清楚这个天才是OP的工作,还是评论员的建议,但这(我认为)是创建26个字母中的可迭代字母的最短方法在罗马字母中。

map(chr,range(97,123))

如果大小写无关紧要,则可以使用大写字母剥离另一个字符:

map(chr,range(65,91))

我使用map太多了,我不知道这是怎么发生的。


4
可能在实际编码中使用它,当对这些东西进行硬编码时,我感到非常愚蠢:')
ToonAlfrink 2014年

37
在实际的编码中,使用string.lowercase-就是这样做的。
凯文S

1
如果您同时需要这两种情况,我知道的最短方法是filter(str.isalpha,map(chr,range(256)))。它仅比s = map(chr,range(256)); s + = map(str.lower,s)
短-quintopia

@quintopia:为什么用256代替122(ord('z'))?除了长度相同外...如果您需要字母数字,请str.isalpha在@quintopia的版本中替换为str.isalnum。(但是,如果只需要一种情况,则整个36个字符的字符串将不超过filter(str.isalnum,map(chr,range(90)))。)
Tim Pederick 2015年

2
如果您不公平并且使用范围为R,则我的版本比您的原始版本短:('%c'*26%tuple(R(97,123))仅24个字符)如果您拼写的range长度与字母一样长-大写版本较短
JBernardo

32

尽管python没有switch语句,但是您可以使用字典来模拟它们。例如,如果您想要这样的开关:

switch (a):
    case 1:
        runThisCode()
        break
    case 2:
        runThisOtherCode()
        break
    case 3:
        runThisOtherOtherCode()
        break

您可以使用if语句,也可以使用以下语句:

exec{1:"runThisCode()",2:"runThisOtherCode()",3:"runThisOtherOtherCode()"}[a]

或这个:

{1:runThisCode,2:runThisOtherCode,3:runThisOtherOtherCode}[a]()

如果所有代码路径都是具有相同参数的函数,则更好。

要支持默认值,请执行以下操作:

exec{1:"runThisCode()"}.get(a,"defaultCode()")

(或这个:)

­­{1:runThisCode}.get(a,defaultCode)()

这样做的另一个优点是,如果确实有冗余,则可以在字典末尾添加它们:

exec{'key1':'code','key2':'code'}[key]+';codeThatWillAlwaysExecute'

如果您只想使用开关来返回值:

def getValue(key):
    if key=='blah':return 1
    if key=='foo':return 2
    if key=='bar':return 3
    return 4

您可以这样做:

getValue=lambda key:{'blah':1,'foo':2,'bar',3}.get(key,4)

2
这是我会深深考虑在野外使用的东西。我真的很想念我的switch声明!+1
HalosGhost

1
尽管在第一个示例中,您无需使用带有数字键的字典,而应使用列表
Cyoce

1
如果你有一个字符串作为键,使用dict(s1=v1,s2=v2,...,sn=vn)的不是{'s1':v1,'s2':v2,...,'sn':vn}节省2 * N-4个字节,是更好,如果N> = 3
黑色猫头鹰凯

31

当您有两个布尔值a和时b,如果要确定ab均为真,请使用*代替and

if a and b: #7 chars

if a*b: #3 chars

如果两个值中的任何一个为false,则它将按0该语句计算,并且整数值只有在非零时才为true。


9
或者,您可以使用&a=b=Falsea&b
ɐɔıʇǝɥʇuʎs2014年

3
使用+or,如果你能保证a != -b
undergroundmonorail

2
|在所有情况下均有效。
CalculatorFeline

1
*而不是and/ &&以多种语言保存一些字节。
wastl

26

利用Python 2字符串表示形式

Python 2使您仅需2个字符x即可将对象转换为其字符串表示形式`x`。使用此选项可完成比对象本身更容易在对象字符串上完成的任务。

加入角色

给定一个字符列表l=['a','b','c'],可以将生''.join(l)成为`l`[2::5],从而节省一个字节。

其原因是`l`"['a', 'b', 'c']"(含空格),所以可以用列表的片段提取信件,开始了第二次零索引字符a,并采取一切第五个字符从那里。这对于连接多字符字符串或转义表示为的字符无效'\n'

连接数字

同样,考虑到数字的非空列表一样l=[0,3,5],可以将它们连接起来成一个字符串'035'作为`l`[1::3]

这样可以省去类似的操作map(str,l)。请注意,它们必须是个位数,并且不能有像1.0混入一样的浮点数。而且,这在空列表上会失败,产生]

检查底片

现在,执行非字符串任务。假设您有一个l实数列表,并且想测试它是否包含任何负数,并生成一个布尔值。

你可以做

'-'in`l`

它检查字符串rep中是否有负号。比任何一个短

any(x<0for x in l)
min(l+[0])<0   

对于第二个,min(l)<0它将在空白列表上失败,因此您必须套期保值。


串联单个数字的字符串切片在Python 3中也有效,尽管效果更差:str(l)[2::5]是12个字节,而对于是19个字节''.join(map(str,l))。出现这种情况的实际情况(其中l是生成器语句,而不是列表)只为我节省了一个字节……还是值得的!
蒂姆·佩德瑞克

25

一行函数可以使用lambda来完成:

def c(a):
  if a < 3: return a+10
  else: return a-5

可以转换为(注意缺少空格3and10or

c=lambda a:a<3and a+10or a-5

21
c=lambda a:a+[-5,10][a<3]。当您取决于短路行为时,和/或技巧更有用
gnibbler 2011年

3
在您的函数中,else: 可以将其删除,以return停止函数的执行,因此,仅在if条件失败(也就是 else条件为真)时才执行随后的所有操作。因此else可以安全地省略。(详细解释了那里的新手)
JeromeJ

c(-10)返回-15,而它应该返回0
Anvit

c=lambda a:a-5+15*(a<3)
JayXon

25

循环最多4个项目可能更适合提供元组而不是使用范围

for x in 0,1,2:

for x in range(3):

24

天花板和地板

如果您想获得除法的四舍五入结果,就像//对下限进行处理一样,则可以使用math.ceil(3/2)15或更短-(-3//2)的8字节。

math.floor(n)   : 13 bytes+12 for import
n//1            : 4  bytes

math.ceil(n)    : 12 bytes+12 for import
-(-n//1)        : 8  bytes

5
这只为我节省了将近20个字节,谢谢!
Morgan Thrapp

1
有时您可以选择使用n//1+1ceil而不是ceil,但这确实意味着ceil(n)= n + 1,但它应该适用于所有非整数值
fejfo

round(x)(x+.5)//1+1字节,但后者以开头(,如果x是一个由常数组成的和,则可能很有用。
user202729 '18

23

使用+=代替appendextend

A.append(B)  

可以缩短为:

A+=B,

B,在这里创建一个元素元组,可以A[B]in中一样用于扩展A+=[B]


A.extend(B)

可以缩短为:

A+=B

5
在许多(但不是全部)情况下,return 0return 1等于return Falsereturn True
Undergroundmonorail

5
(1)仅在您已经知道数字为负数的情况下才有效,在这种情况下,您只需使用减号即可再保存2个字符。-x而不是x*-1--8.32而不是-8.32*-1。或者只是8.32...
trichoplax 2014年

引用OP:请为每个答案发布一个提示。
nyuszika7h 2014年

请注意,在中A+=B B是个tuple
暴民埃里克(Erik the Outgolfer)

23

根据条件选择两个数字之一

已经知道对三元表达式[x,y][b]使用带有布尔值的列表选择。变量,和也可以是表达式,尽管请注意,即使未选择,它们和也会被求值。by if b else xxybxy

xy是数字时,这是一些潜在的优化方法。

  • [0,y][b] -> y*b
  • [1,y][b] -> y**b
  • [x,1][b] -> b or x
  • [x,x+1][b] -> x+b
  • [x,x-1][b] -> x-b
  • [1,-1][b] -> 1|-b
  • [x,~x][b] -> x^-b
  • [x,y][b] -> x+z*b(或y-z*b),其中z = yx。

您也可以切换xy如果可以重写则b取而代之。


22

使用〜从列表的后面索引

如果L是列表,则用于从背面L[~i]获取第i'th个元素。

这是的i逆向的'th要素L。位补码~i等于-i-1,因此修复了的偏离一错误L[-i]


21

PEP448 – 其他拆包概述

随着Python 3.5的发布,列表,元组,集合和字典的操作变得更加容易。

将迭代器转换为集合/列表

比较对:

set(T)
{*T}

list(T)
[*T]

tuple(T)
(*T,)

矮得多!但是请注意,如果只想将某些内容转换为列表并将其分配给变量,则正常的扩展可迭代解压缩会更短:

L=[*T]
*L,=T

类似的语法适用于元组:

T=*L,

这就像扩展的可重复拆包一样,但另一边带有星号和逗号。

联接列表/元组

如果您需要在两边都附加一个列表/元组,则解压缩比串联要短一些:

[1]+T+[2]
[1,*T,2]

(1,)+T+(2,)
(1,*T,2)

打印多个列表的内容

这不限于print,但肯定是大部分里程来自何处。PEP448现在允许多次拆包,如下所示:

>>> T = (1, 2, 3)
>>> L = [4, 5, 6]
>>> print(*T,*L)
1 2 3 4 5 6

更新多个词典项目

这可能不会经常发生,但是如果要更新至少三个项目,则可以使用该语法来节省更新字典的时间:

d[0]=1;d[1]=3;d[2]=5
d={**d,0:1,1:3,2:5}

这基本上消除了对的任何需求dict.update


6
这看起来比Perl差,但确实有效……
Mega Man

20

更改import *import*


如果您没有听到,请import*保存字符!

from math import*

的长度仅比1个字符长import math as m,您可以删除的所有实例m.

即使一次使用也可以节省!


19
>>> for i in range(x):s+=input()

如果i的值无用:

>>> for i in[0]*x:s+=input()

要么

>>> exec's+=input();'*x

8
您可以将第二个示例放入for i in[0]*x:s+=input()以节省其他空间。另外,您可以删除exec和第一个引号之间的空间以获取exec's+=input();'*x
Justin Peel

第二行不应该是:for i in[0]*x:s+=input()
micsthepick

Dupe(更新但更多支持)
user202729 '18
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.