Pythonでのゴルフのヒント


248

Pythonでゴルフをするための一般的なヒントは何ですか?私は、コードゴルフの問題に適用でき、Pythonに少なくともある程度固有のアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。

回答ごとに1つのヒントを投稿してください。


27
ああ、私は、各言語のために来て、このような質問のセット全体を見ることができます...
R.マルティーニ・フェルナンデス

4
@Marthinho同意します。C ++に相当するものを開始しました。しかし、これらの質問タイプの多くで同じ回答が再投稿されない限り、それは悪いことではないと思います。
マーコグ

50
質問を愛するが、私は自分自身を語って維持する必要があり、「これが唯一の楽しみのためではない製品コードのためにある」
グレッグ・グイダ

2
この質問はコミュニティWikiの投稿ではありませんか?
ドルカハン

3
@dorukayhan Nope; これは有効なコードとゴルフの ヒントの質問であり、CGの目的でPythonコードを短縮するためのヒントを求めています。そのような質問はサイトにとって完全に有効であり、これらのタグのいずれも、CGチャレンジをCWする必要があるSOとは異なり、質問をCWする必要があると明確に述べていません。また、良い答えを書いて、そのようなヒントを見つけることは常に何かに値します。質問がコミュニティwiki(rep)である場合、それは取り除かれます。
エリックアウトゴルファー16

回答:


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] = [1]から実際に異なっていると、b = [1]
isaacg

6
最初のヒントの面白いところは、Javaでも機能することです。
ジャスティン14

1
はい@Justinが、唯一のプリミティブ型を持つ
HyperNeutrino

11
ただし、すべての変数が同じインスタンスを指すため、a = b = c = []またはオブジェクトのインスタンス化は絶対に使用しないでください。それはおそらくあなたが望むものではありません。
PHE

146

条件は長くなる場合があります。場合によっては、単純な条件をで置き換えることができます(a,b)[condition]。場合はconditiontrueで、それからb返されます。

比較する

if a<b:return a
else:return b

これに

return(b,a)[a<b]

37
これらはまったく同じではありません。最初のものは返される式のみを評価し、2番目のものは常に両方を評価します。:これらのものは、短絡を行うa if a<b else ba<b and a or b
マリナス

3
(lambda(): b, lambda(): a)[a < b]()ラムダを使用して独自のショートを作る
明唐は、

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
ラムダは条件式よりもずっと長いです。
user2357112 14年

18
@ user2357112しかし、それらを使用すると、格段にかっこよくなります。:]
チェイスリース14年

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この方法で演算子を回避することもできます。例えば、もしabcおよびd整数であり、

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

次のように1文字短縮できます。

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

これは、すべてのリストが整数よりも大きいことを使用します。

場合cdリストである、これはさらに良くなります:

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

22
もちろん、これが実際にゴルフされた場合は3>a>1<b<5
Rafe Kettler

4
対称性が大好きです。$ aの分を見つけ、$ Bの古いPerlのゴルフトリックを思い出させる:[$a => $b]->[$b <= $a]:)
サイモン・ウィテカー

第二の例は、(なしリスト)もして行うことができることに注意してくださいif(a<b)+(c>d):foo()
WorldSEnder

6
+はaでなければなりません*orだろう+
WorldSEnder


103

組み込み関数を繰り返し使用している場合、異なる引数を使用している場合は、新しい名前を付けるとスペース効率が向上する場合があります。

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

6
ただし、実際にはバイトを保存しませんでした。
user2357112 14年

4
r = rangeで、他の2つのrは9文字です。範囲を2回使用すると、10文字になります。この例では大きな節約ではありませんが、必要なのは、大幅な節約を確認するためにもう1回範囲を使用することだけです。
フランク

13
@Frank追加の改行は別の文字です。
L3viathan

2
実際、2回の繰り返しは長さが5の関数名で保存するには少なすぎます。必要なもの:長さ2:6人、長さ3:4人、長さ4または5:3人、長さ6以上:2人。AKA(長さ-1)*(reps-1)> 4。
Ørjanヨハンセン

これは、一流の機能を持つすべての言語に適用されることに注意してください。
bfontaine

94

Pythonコードでは、2レベルのインデントが必要な場合があります。明らかなことは、各インデントレベルに1つと2つのスペースを使用することです。

ただし、Python 2はタブ文字とスペース文字を異なるインデントレベルと見なします。

つまり、最初のインデントレベルは1つのスペース、2番目のインデントレベルは1つのタブ文字にすることができます。

例えば:

if 1:
 if 1:
\tpass

\tタブ文字はどこですか。


1
クール、私はこれについて考えたことがありません!
ジュールオレオン

97
これはpython3で失敗します:スペースとタブを混在させることはできません(codegolfにとっては悪いことですが、他のすべての場合は良いことです)。
バクリウ

1
Python 3.4では、これはうまく機能しているようです。
-trichoplax

3
@trichoplax、Python 3.4.3で私は得るTabError: inconsistent use of tabs and spaces in indentation.
-ceilingcat

参考までに、タブには8つのスペースがあります。
エリックアウトゴルファー

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))バイト長。

これら3つのオプションで保存されたバイトのプロットplainから、次のことがわかります。

  • 以下のためのn <5つのラムダ、あなたはまったく空想何もしていない方がいいでしょう。
  • 以下のための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
ただし、機能する場合は非常に役立ちます。
地下

面白い、これさえ考えられない!
クラウディウ14

私はpythonをベースにした言語でラムダの新しい演算子を追加しました:=>is the string = lambda です。たとえば、にf=>:0なりますf = lambda: 0
-NoOneIsHere

78

拡張スライスを使用して、多数の文字列から1つの文字列を選択します

>>> 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

このブール2文字列の場合、次のように書くこともできます。

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導き出されるかということです。
ニブラー

72

を使用`n`する代わりに、整数を文字列に変換するために使用しstr(n)ます。

>>> n=123
>>> `n`
'123'

38
いいですが、Python3では動作しません。
アレクサンドル

2
注意:整数では実際に機能しますが、たとえば文字列では機能しません。
ナキロン

41
ところで。`` reprの略です
アレクサンドル

9
-2 ** 31より小さい整数または2 ** 31-1(長い)より大きい整数は、最後に「L」が付加されます。
-hallvabo

6
これは、フロートを完全な精度で印刷するためにも使用できます
ニブラー

69

ルックアップテーブルをマジックナンバーとして保存する

最初の12個の英語の数字のどれにが含まれているかのように、ブールルックアップテーブルをハードコーディングするとします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

得られたと0、または1等しいことFalseTrue

アイデアは、マジック番号がビット列としてのテーブルを記憶することであるbin(3714)= 0b111010000010と、n(端部から)番目の桁は、対応するn番目のテーブルエントリを。n番号nスペースを右にビットシフトして最後の数字を取ることでthエントリーにアクセスします&1

この保管方法は非常に効率的です。代替案と比較してください

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

ルックアップテーブルに、次のように抽出できるマルチビットエントリを保存できます。

 340954054>>4*n&15

関連する4ビットブロックを抽出します。


4ビットブロックの結果の例はありますか?nビットブロックのルールを使用しましたか?
JeromeJ

8
六角は時々さらに小さくなるかもしれません。
ジョナザン

4
これは多くの言語で役立ちます。
チョイス

1
@Joonazan Hexは、999 999を超える数値では小さくなります。
Mateen Ulhaq

60

2つの数値ループを1つに折りたたみます

m*nグリッドのセルを繰り返し処理しているとします。for行用と列用の2つのネストされたループの代わりに、通常、1つのループを使用し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)

実際には、2つの範囲のデカルト積を反復処理し、ペアを(i,j)としてエンコードしx=i*n+jます。コストのかかるrange呼び出しとループ内のインデントのレベルを節約しました。繰り返しの順序は変わりません。

使用//するのではなく、/あなたが参照している場合はPython 3にiし、j何度も、それらの値を割り当てるために速いかもしれi=k/nj=k%nループ内。


5
これはすごい。これが可能だとは思っていませんでした!
-theonlygusti

これはJavaScriptのヒントで見ました。これは、ほとんどの言語で非常に便利なトリックです。
チョイス

7
参考のために、これを3つのループに拡張するには:for i in range(m*n*o): do_stuff(i/n/o,i%(n*o)/o,i%o)
mbomb007

3
for nループ:repl.it/EHwa
mbomb007

場合によってはitertools.product、特にデカルト積を生成する場合、ネストされたループよりもはるかに簡潔になります。a1, a2, b1, b2デカルト積の例であり、'ab'かつ'12'
Aaron3468

54

次のトークンがeまたはで始まらない限りE。数字に続くスペースを削除できます。

例えば:

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

になる:

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

複雑な1行のステートメントでこれを使用すると、かなりの文字を節約できます。

編集:@marcogが指摘したように、4or a動作しますがa or4、これが変数名と混同されると動作しません。


37
if(i,j)==(4,4):はさらに短く、この特別な場合ではif i==j==4:
ニブラー

3
関連:4or a動作しますが、そうではありませんa or4
-marcog

17
0or動作しません(0o8進数の接頭辞です)。
ナブ

5
以来、それは、とにかく重要ということはない@Nabb 0 or x常につもりリターンですx。同様に切り取り0 orます。
ɐɔıʇǝɥʇuʎs

5
0orただし、長い数字の一部としては問題ありません。10 or xはと同等10or xです。
センモウヒラムシ

54

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
今日私が出会ったこのトリックのバリエーション:-~-x1バイト対(1-x)
リン

4
別の有用なアプリケーションは、a+b+1より簡潔にとして記述できることですa-~b
ストリゴイデス

そしてn-i-1ちょうどn+~iです。
ruohola

51

iterableを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セグメンテーション違反でインタラクティブなpython3をクラッシュします:(
daniero

@danieroうわー。対話型コンソールのみですか?非常に奇妙に聞こえます。きれいなコンソールで試してみるか、バグを報告
JBernardo

1
私のPython 3.5は問題なく動作します。
-NoOneIsHere

I =(X ** 2範囲内のxの(5))私はこのコードは<ジェネレータオブジェクト<genexpr> 0x03321690で>返さ取得
ジョージ

7
式でこれを実行している場合、実行できます[*'abcde']
エソランジングフルーツ

46

の代わりにrange(x)*実際に値を使用する必要がない場合は、任意のリストで演算子を使用できますi

for i in[1]*8:pass

とは対照的に

for i in range(8):pass

これを2回以上行う必要がある場合は、変数に反復可能変数を割り当て、その変数に必要な範囲を掛けることができます。

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 14

7
exec"pass;"*8大幅に短くなります。
DJMcMayhem

1
が8の場合r=1r*8数値を反復処理できません。私はあなたが意味を推測r=[1]
アルテミス家禽

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

状況によっては、これを使用して最初の要素を取得して括弧を保存することもできます。

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=[]何度も書いています。これほど簡単なものに文字を保存できるのは驚くべきことです。
xnor 14

@xnor grcに感謝します。他の要素が1つしかないため、それほど良くはありませんが(a,*L=1,)、1文字を節約できます:)
Sp3000 14

リストの最初と最後の両方の要素も取得できることを忘れないでくださいa,*_,b=L
チョイス

36

Python2.7でリテラルを設定する

このようなセットを書くことができS={1,2,3}ます。これは、1文字を保存する{e}&S代わりにe in Sを使用してメンバーシップをチェックできることも意味します。


4
またif、スペースがないため、これにより文字がsに保存されます(if{e}&S:
アーティアー

1
あなたは置き換えることができることに注意not inすることによって{e}-S、そのトリックを
ブラックフクロウカイ

35

長い間、アルファベット全体を手に入れるための短い方法を考えることができなかったことが気になりました。あなたがあなたのプログラムで持つ価値があるrange十分にそれを使うならR=range

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

ナイーブよりも短い

'abcdefghijklmnopqrstuvwxyz'

、それ以外の場合は1文字だけ長くなります。ascii値の知識を必要とする賢い人は、すべての文字を入力するだけでなく、より冗長になってしまったことを思い出しました。

私の娘のアルファベットのこの答えを見るまで。私はこの天才がOPの作品であるか、それがコメンターによる提案であったかどうかを理解するのに十分なほど編集履歴を追跡することはできませんが、これは26文字の反復可能なものを作成する最短の方法です(私は信じています)ローマ字で。

map(chr,range(97,123))

大文字と小文字が区別されない場合は、大文字を使用して別の文字を削除できます。

map(chr,range(65,91))

私はmapあまりにも多くの方法を使います、私はこれが私に決して起こらなかった方法を知りません。


4
これらの事をハードコーディングするとき、実際のコーディングでこれを使用する場合があります、私は愚かな感じ: ')
ToonAlfrink

37
実際のコーディングでは、使用しますstring.lowercase-それが目的です。
ケビンS

1
両方のケースが必要な場合、私が知っている最短の方法はfilter(str.isalpha、map(chr、range(256)))です。s = map(chr、range(256)); s + = map(str.lower、s)よりわずかに短い
-quintopia

@quintopia:なぜ122(ord('z'))ではなく256 ですか?同じ長さであることに加えて...また、英数字が必要な場合はstr.isalpha、@ quintopiaのバージョンをに置き換えますstr.isalnum。(しかし、あなたは1例のみが必要な場合は、全体の36文字の文字列がよりもはやありませんfilter(str.isalnum,map(chr,range(90)))。)
ティムPederick

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)()

これのもう1つの利点は、冗長性がある場合、辞書の最後に追加できることです。

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 14年

1
最初の例で番号付きキーを持つ辞書を使用する代わりに、リストを使用する必要があります
-Cyoce

1
あなたがキーとして文字列を持っている場合は、使用してdict(s1=v1,s2=v2,...,sn=vn)の代わりには、{'s1':v1,'s2':v2,...,'sn':vn}2 * N-4バイトを保存し、N> = 3ならば良いです
ブラックフクロウカイ

31

2つのブール値があり、aとのb両方がtrueであるかどうかを確認する場合はa、代わりにをb使用します。*and

if a and b: #7 chars

if a*b: #3 chars

いずれかの値が偽の場合0、そのステートメントのように評価され、整数値はゼロ以外の場合にのみ真になります。


9
それとも、使用することができます&a=b=Falsea&b
ɐɔıʇǝɥʇuʎs

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]、as を生成してバイトを節約できます。

その理由は、すなわち`l`ある "['a', 'b', 'c']"一つの第二のゼロインデックス付き文字ことを開始して、リストのスライスに文字を抽出することができるように、(スペースで)a、そこからすべての5番目の文字を取ります。これは、複数文字の文字列を結合したり、のように表現されたエスケープ文字には機能しません'\n'

数字を連結する

同様に、のような数字の空でないリストが与えられた場合l=[0,3,5]、それらを'035'として文字列に連結できます`l`[1::3]

これにより、次のような操作を省くことができmap(str,l)ます。それらは1桁でなければならず、1.0混在するような浮動小数点数を持つことはできません。また、これは空のリストで失敗し、を生成し]ます。

ネガを確認

これで、非文字列タスクの場合。l実数のリストがあり、負数が含まれているかどうかをテストして、ブール値を生成するとします。

できるよ

'-'in`l`

これは、文字列repの負符号をチェックします。これは、

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

2つ目はmin(l)<0、空のリストで失敗するため、ヘッジする必要があります。


1桁の文字列スライシングを連結することはPython 3でも効果的ですが、それほどではありませんが:str(l)[2::5]は12バイトで、19バイトです''.join(map(str,l))。これが発生した実際の状況(lリストではなく、ジェネレーターステートメントがあった)で1バイトだけ節約できました...まだ価値があります!
ティムペデリック

25

ラムダを使用して1行の関数を実行できます。

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]。and / orトリックは、短絡動作に依存している場合に便利です
ニブラー

3
関数では、関数の実行を停止するときにelse: ドロップできますreturn。したがって、後続のすべては、if条件が失敗した場合、つまりelse条件がtrueの場合に のみ実行されます。したがって、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バイト近く節約できました、ありがとう!
モーガンスラップ

1
時には、あなたが離れて得ることができるn//1+1代わりに、切り上げのが、それはCEIL(n)を意味= N + 1が、それはすべての非整数値のために働く必要がない
fejfo

round(x)(x+.5)//1+1バイトですが、後者はで始まり、定数で構成される合計の(場合xは便利です。
user202729

23

andの+=代わりに使用appendextend

A.append(B)  

以下に短縮できます。

A+=B,

B,ここでは、のAよう[B]に拡張するために使用できる1要素のタプルを作成しA+=[B]ます。


A.extend(B)

以下に短縮できます。

A+=B

5
多くの(すべてではない)の場合には、return 0またはreturn 1同等ですreturn Falsereturn True
地下

5
(1)既に負の数であることがわかっている場合にのみ機能します。この場合、マイナス記号を使用するだけでさらに2文字を保存できます。-xではなくx*-1--8.32ではなく-8.32*-1。それとも8.32...
センモウヒラムシ

OPの引用:回答ごとに1つのヒントを投稿してください。
nyuszika7h 14年

その中には注意A+=B Bですtuple
エリックアウトゴルファー16年

23

条件に基づいて2つの数値のいずれかを選択する

あなたはすでに知っているリストの選択を使用するように[x,y][b]、ブールとb三元の発現のためにy if b else x。変数xyおよびb、両方のことに注意してくださいしかし、表現することができxかつがy選択されていない場合でも、評価されます。

xおよびyが数値である場合の潜在的な最適化を次に示します。

  • [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。

また、切り替えることができますxし、yあなたが書き換えることができればb代わりにその否定します。


22

〜を使用してリストの後ろからインデックスを作成します

Lリストの場合、を使用L[~i]iて、後ろから '番目の要素を取得します。

これはの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

複数の辞書項目を更新する

これはおそらくそれほど頻繁には発生しませんが、少なくとも3つの項目を更新する場合は、構文を使用して辞書の更新を節約できます。

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

これは基本的にを必要としませんdict.update


6
...これはPerlのよりも悪いように見えますが、それは動作します
ロックマン

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
2番目の例を作成して、for i in[0]*x:s+=input()別のスペースを節約できます。また、execと取得する最初の引用符の間のスペースを削除することができますexec's+=input();'*x
ジャスティンピール

2行目は次のとおりではありませんfor i in[0]*x:s+=input()
。– micsthepick

デュープ(新しいがより多くの賛成票)
-user202729
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.