파이썬에서의 골프 팁


248

파이썬에서 골프를 할 때 어떤 일반적인 팁이 있습니까? 코드 골프 문제에 적용 할 수 있고 적어도 파이썬에 특정한 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다).

답변 당 하나의 팁을 게시하십시오.


27
오, 나는 각 언어마다 이와 같은 질문을 볼 수 있습니다 ...
R. Martinho Fernandes

4
@Marthinho 동의합니다. C ++에 해당 하는 방금 시작했습니다 . 그러나 이러한 많은 질문 유형에 동일한 답변이 다시 게시되지 않는 한 그 나쁜 점은 생각하지 않습니다.
marcog

50
질문을 사랑하지만 자신을 계속 얘기해야 "이것은 단지 재미를 위해 NOT 생산 코드입니다"
그렉 GUIDA

2
이 질문이 커뮤니티 위키 게시물이 아니어야합니까?
dorukayhan

3
@dorukayhan Nope; 유효한 코드 골프 질문이며 CG 목적으로 파이썬 코드 단축에 대한 팁을 요구 합니다. 이러한 질문은 사이트에 완벽하게 유효하며 이러한 태그 중 어느 것도 CG 과제를 CW로 처리해야하는 SO와 달리 질문을 CW로해야한다고 명시 적으로 언급하지 않습니다. 또한 좋은 답변을 작성하고 그러한 팁을 찾는 것은 항상 뭔가 가치가 있습니다. 질문은 커뮤니티 위키 (rep)입니다.
Outgolfer Erik

답변:


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에서도 작동한다는 것입니다.
저스틴

1
@Justin 네,하지만 기본 유형 만 사용
HyperNeutrino

11
그러나 모든 변수가 동일한 인스턴스를 가리 키므로 a = b = c = [] 또는 객체 인스턴스를 사용하지 마십시오. 아마 당신이 원하는 것이 아닙니다.
PhE

146

조건부는 길 수 있습니다. 경우에 따라 간단한 조건부를로 바꿀 수 있습니다 (a,b)[condition]. 경우 condition사실, 다음 b반환됩니다.

비교

if a<b:return a
else:return b

이에

return(b,a)[a<b]

37
이것들은 정확히 동일하지 않습니다. 첫 번째는 반환 된 식만 평가하고 두 번째는 항상 두 식을 모두 평가합니다. :이 사람은 단락을 수행 a if a<b else b하고a<b and a or b
스 marinus

3
(lambda(): b, lambda(): a)[a < b]()람다와 함께 자신의 단락을 만들어
Ming-Tang

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

18
@ user2357112 그러나 그들은 당신이 그들을 사용할 때 훨씬 더 시원하게 보이게합니다. :]
Chase Ries

117

내가 한 번 큰 일은 :

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

대신에:

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

파이썬의 비교 연산자는 흔들린다.


파이썬 2에서는 모든 것을 비교할 수 있으므로 and이런 식으로 연산자를 피할 수도 있습니다 . 예를 들어, a, b, cd정수는,

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
대칭을 좋아하십시오. 다음 $ A의 최소 및 B $ 찾는 오래된 펄 골프 트릭을 생각 나게 [$a => $b]->[$b <= $a]:)
사이먼 휘태커

두 번째 예 (목록 없음)는if(a<b)+(c>d):foo()
WorldSEnder

6
+는이어야합니다 *. 는 or+
WorldSEnder

1
foo()if 3>a>1<b<5
Outgolfer Erik

103

내장 함수를 반복해서 사용하는 경우 다른 인수를 사용하는 경우 새 이름을 지정하는 것이 공간 효율적일 수 있습니다.

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

6
그래도 실제로 바이트를 저장하지 않았습니다.
user2357112

4
r = 범위이고 다른 두 r은 9 자입니다. 범위를 두 번 사용하면 10 자입니다. 이 예제에서는 크게 절약 할 수는 없지만 상당한 절약을 위해 범위를 한 번 더 사용하면됩니다.
Frank

13
@Frank 추가 줄 바꿈은 또 다른 문자입니다.
L3viathan

2
실제로 두 번의 반복은 길이가 5 인 함수 이름을 저장하기에는 너무 적습니다. 길이 2 : 6 반복, 길이 3 : 4 반복, 길이 4 또는 5 : 3 반복, 길이> = 6 : 2 반복. AKA (길이 -1) * (응답 -1)> 4.
Ørjan Johansen

이것은 일급 기능을 가진 모든 언어에 적용됩니다.
bfontaine

94

때때로 파이썬 코드에는 2 단계의 들여 쓰기가 필요합니다. 분명한 것은 들여 쓰기 수준마다 하나와 두 개의 공백을 사용하는 것입니다.

그러나 Python 2는 탭과 공백 문자가 다른 들여 쓰기 수준으로 간주합니다.

즉, 첫 번째 들여 쓰기 수준은 공백이되고 두 번째는 탭 문자가 될 수 있습니다.

예를 들면 다음과 같습니다.

if 1:
 if 1:
\tpass

\t탭 문자는 어디에 있습니까 ?


1
쿨, 나는 이것에 대해 생각하지 않았다!
Jules Olléon

97
이것은 python3에서 실패합니다 : 더 이상 공백과 탭을 혼합 할 수 없습니다 (코드 골프에는 좋지 않지만 다른 모든 경우에는 좋은 것입니다).
Bakuriu

1
파이썬 3.4에서는 이것이 잘 작동하는 것 같습니다.
trichoplax

3
@ trichoplax , python 3.4.3에서TabError: inconsistent use of tabs and spaces in indentation.
ceilingcat

참고로 탭은 8 칸의 가치가 있습니다.
Outgolfer Erik

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))바이트.

A로부터 의 플롯 을 통해 저장된 바이트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은 엄청납니다.
boothby

4
그래도 작동하면 많은 도움이됩니다.
undergroundmonorail

흥미롭고 결코 이것을 생각하지 마십시오!
Claudiu

내가 파이썬 기반으로 내 언어로 람다위한 새로운 연산자를 추가 : =>그냥 문자열입니다 = lambda . 예를 들어, f=>:0입니다 f = lambda: 0.
NoOneIsHere 여기

78

확장 슬라이싱을 사용하여 여러 문자열 중에서 하나의 문자열을 선택하십시오.

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

vs

>>> 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파생 되는지는 골프 솔루션의 또 다른 부분 일 것입니다.
gnibbler 2016 년

72

다음 `n`을 사용 하는 대신 정수를 문자열로 변환하는 데 사용하십시오 str(n).

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

38
훌륭하지만 Python3에서는 작동하지 않습니다.
Alexandru

2
주의 : 실제로 정수는 작동하지만 문자열은 작동하지 않습니다.
Nakilon

41
btw. ``repr의 줄임말
Alexandru

9
-2 ** 31보다 작거나 2 ** 31-1보다 큰 정수 (Longs)는 끝에 'L'이 붙습니다.
hallvabo

6
플로트를 최대 정밀도로 인쇄하는 데 사용할 수도 있습니다
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

결과로 0또는 1이상임 FalseTrue.

매직 번호는 테이블을 비트 열 bin(3714)= 으로 저장하고 0b111010000010,- n번째 숫자 (끝부터)는 nth 테이블 항목에 해당합니다 . n숫자 n공간을 오른쪽 으로 비트 시프 팅 하고 마지막 자리를로 이동 하여 th 엔트리에 액세스합니다 &1.

이 저장 방법은 매우 효율적입니다. 대안과 비교

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

룩업 테이블에 다음과 같이 추출 할 수있는 멀티 비트 항목을 저장할 수 있습니다.

 340954054>>4*n&15

관련 4 비트 블록을 추출합니다.


4 비트 블록에 대한 예제 결과가있을 수 있습니까? n 비트 블록에 규칙을 사용 했습니까?
JeromeJ

8
16 진수는 때때로 더 작을 수도 있습니다.
Joonazan

4
이것은 많은 언어에 유용합니다.
Cyoce

1
@Joonazan Hex는 999,999 를 초과하는 숫자보다 작습니다 .
Mateen Ulhaq 2016 년

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루프 내에서 비용이 많이 드는 호출과 들여 쓰기 수준을 저장했습니다 . 반복 순서는 변경되지 않습니다.

사용 //대신에 /당신을 참조하면 파이썬 3에서 ij많은 시간, 그들의 값을 할당하는 것이 속도가 더 빠를 수 있습니다 i=k/n, j=k%n루프 내부.


5
대단해. 나는 이것이 가능하다는 것을 결코 깨닫지 못했다!
theonlygusti

JavaScript 팁에서 이것을 보았습니다. 대부분의 언어에서 매우 유용한 트릭입니다.
Cyoce

7
참고로, 이것을 3 개의 루프로 확장하려면 :for i in range(m*n*o): do_stuff(i/n/o,i%(n*o)/o,i%o)
mbomb007

3
대한 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

복잡한 한 줄 문장에서 이것을 사용하면 문자를 상당히 줄일 수 있습니다.

편집 : @marcog가 지적했듯이 4or a작동하지만 a or4변수 이름과 혼동 되지 는 않습니다 .


37
if(i,j)==(4,4):if i==j==4:
짧고이

3
관련 : 4or a작품, 그러나a or4
marcog

17
0or또한 작동하지 않습니다 ( 0o8 진수의 접두사입니다).
Nabb

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 바이트를 절약 (1-x)합니다.
Lynn

4
또 다른 유용한 응용 프로그램은 a+b+1로보다 간결하게 작성할 수 있습니다 a-~b.
Strigoides 2012 년

그리고 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'한 다음 ssegfault로 대화 형 python3 을 충돌
시킵니다

@daniero 와우. 대화식 콘솔에서만? 매우 이상하게 들린다. 깔끔한 콘솔에서 시도하거나 버그를보고하십시오
JBernardo

1
내 파이썬 3.5는 잘 작동합니다.
NoOneIsHere

내가 = (x ** 2 범위 (5) 범위 x)에 대해이 코드는 0x03321690에서 <generator 객체 <genexpr>을 반환했습니다.
george

7
그리고 당신이 표현에서 이것을하고 있다면, 당신은 할 수 있습니다 [*'abcde'].
Esolanging 과일

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...이지 않기 때문에 공간을 절약 할 수 있다는 것 "이라고 생각했습니다.
undergroundmonorail

아, 이해하지 못했습니다. 지금 수정
자랑스런 헤 켈러

7
exec"pass;"*8상당히 짧습니다.
DJMcMayhem

1
경우 r=1, r*88, 당신은 숫자를 반복 할 수 없다. 나는 당신이 의미하는 것 같아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

우리는 이미 이것을 사용 하여 파이썬 3에서 iterable을 목록으로 바 꾸었습니다 .

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=[]여러 번 썼다 . 이렇게 간단하게 문자를 저장할 수 있다는 것은 놀라운 일입니다.
xnor

@xnor grc 덕분입니다. 다른 요소가 하나만 있으면 좋지 않습니다 ( a,*L=1,). 그러나 여전히 하나의 문자를 저장합니다 :)
Sp3000

다음을 사용하여 목록의 첫 번째 요소와 마지막 요소를 모두 얻을 수 있음을 잊지 마십시오.a,*_,b=L
Cyoce

36

Python2.7에서 리터럴 설정

이와 같이 세트를 작성할 수 있습니다. S={1,2,3}이는 또한 하나의 문자를 저장 하는 {e}&S대신 멤버쉽을 확인할 수 있음을 의미합니다 e in S.


4
그리고 이것은 if공백이 없기 때문에 캐릭터를 s에 저장합니다 ( if{e}&S:)
Artyer

1
당신이 대체 할 수 있습니다 not in에 의해 {e}-S그 트릭
블랙 올빼미 카이에게

35

여러 해 동안 나는 알파벳 전체를 얻을 수있는 짧은 방법을 생각할 수 없다는 것을 귀찮게했습니다. 프로그램에 range충분한 R=range가치가 있다면

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

순진한 것보다 짧다

'abcdefghijklmnopqrstuvwxyz'

하지만 그렇지 않으면 단일 문자로 길어집니다. ASCII 값에 대한 약간의 지식이 필요한 영리한 사람은 모든 문자를 입력하는 것보다 더 장황하다는 결론을 얻었습니다.

내 딸의 알파벳에 대한 답변을 볼 때까지 . 이 천재가 OP의 작품인지 또는 주석 작성자의 제안인지 알아낼 수있을 정도로 편집 기록을 잘 따를 수는 없지만 26 글자의 iterable을 만드는 가장 짧은 방법입니다 (믿습니다) 로마 알파벳으로.

map(chr,range(97,123))

대소 문자가 중요하지 않은 경우 대문자를 사용하여 다른 문자를 제거 할 수 있습니다.

map(chr,range(65,91))

나는 map너무 많이 사용, 이것이 나에게 어떻게 발생했는지 모르겠어요.


4
실제 코딩에서 이것을 사용할 수 있습니다. 하드 코딩 할 때 너무 바보 같은 느낌이
듭니다

37
실제 코딩에서는 사용하십시오 string.lowercase.
Kevin S

1
두 경우 모두 필요한 경우 내가 아는 가장 짧은 방법은 filter (str.isalpha, map (chr, range (256)))입니다. s = map (chr, range (256)); s + = map (str.lower, s)
보다 약간 짧습니다

@ Quintopia : 왜 122 ( ord('z')) 대신 256 입니까? 영숫자가 필요한 경우 str.isalpha@quintopia의 버전을로 바꾸십시오 str.isalnum. (당신은 단지 하나의 사건을 필요로하지만, 전체 36 문자열보다 더 이상 없습니다 filter(str.isalnum,map(chr,range(90))).)
팀 Pederick

2
당신이 불공평하고 범위를로 사용한다면 R, 내 버전은 원래 버전보다 짧습니다 : '%c'*26%tuple(R(97,123))(24 자 만) 철자 range가 알파벳의 길이만큼 길다면 – 대문자 버전이 짧습니다
JBernardo

32

파이썬에는 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
이것은 내가 야생에서 사용하는 것을 깊이 고려할 것입니다. 나는 나의 스위치 진술을 그리워한다! +1
HalosGhost

1
첫 번째 예에서 번호가 매겨진 키가있는 사전을 사용하는 대신 목록을 사용해야합니다.
Cyoce

1
문자열을 키로 사용하는 경우 dict(s1=v1,s2=v2,...,sn=vn)대신 {'s1':v1,'s2':v2,...,'sn':vn}2 * n-4 바이트 를 저장하고 n> = 3 인 경우 더 좋습니다.
Black Owl Kai

31

두 개의 부울 값이, 때 ab당신이 모두 있는지 확인하려는 경우 ab해당 사용하는 *대신 and:

if a and b: #7 chars

vs

if a*b: #3 chars

둘 중 하나의 값이 false이면 0해당 명령문에서와 같이 평가되며 정수 값은 0이 아닌 경우에만 true입니다.


9
또는 당신은 사용할 수 있습니다 &: a=b=False,a&b
ɐɔıʇǝɥʇuʎs

3
사용 +을 위해 or당신이 보증되는 경우에a != -b
undergroundmonorail

2
|모든 상황에서 작동합니다.
CalculatorFeline

1
*and/ 대신 &&에 많은 언어로 일부 바이트를 저장합니다.
wastl

26

Python 2 문자열 표현 활용

Python 2를 사용하면 단 2 개의 문자만으로도 객체 x를 문자열 표현으로 변환 할 수 있습니다 `x`. 객체 자체보다 객체의 문자열에서 더 쉬운 작업에 사용하십시오.

캐릭터 가입

문자 목록이 주어지면 as 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목록이 아닌 생성기 명령문 이있었습니다 )은 1 바이트 만 절약했습니다 ... 여전히 가치가 있습니다!
Tim Pederick

25

람다로 한 줄 기능을 수행 할 수 있습니다.

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

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:

vs

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+1대신에 천장을 만들다의하지만 CEIL (N)을 의미 하는가 = N + 1이지만이 아닌 모든 정수 값에 대해 작동합니다
fejfo

round(x)(x+.5)//1+1 바이트이지만 후자는로 시작 하며 상수로 구성된 합 (이면 x유용 할 수 있습니다.
user202729

23

사용 +=대신 append하고extend

A.append(B)  

단축 할 수 있습니다 :

A+=B,

B,여기서 확장하는데 사용될 수있는 하나의 요소 터플 생성 A마찬가지로 [B]하여 A+=[B].


A.extend(B)

단축 할 수 있습니다 :

A+=B

5
많은에서는 (전부는 아니지만)의 경우, return 0또는 return 1동일하다 return Falsereturn True.
undergroundmonorail

5
(1) 숫자가 음수임을 이미 알고있는 경우에만 작동합니다.이 경우 빼기 기호를 사용하여 2자를 더 저장할 수 있습니다. -x오히려 x*-1. --8.32오히려 -8.32*-1. 아니면 그냥 8.32...
trichoplax

OP 인용 : 답변 당 하나의 팁을 게시하십시오.
nyuszika7h

in A+=B B은입니다 tuple.
Outgolfer Erik

23

조건에 따라 두 숫자 중 하나를 선택

당신은 이미 알고 목록 선택을 사용하는 [x,y][b]부울와 b삼항 표현 y if b else x. 변수는 x, yb도 표현 될하지만 모두주의 수 xy도 평가 선택하지 않은 경우.

다음은 몇 가지 잠재적 인 최적화의 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후면에서 '번째 요소입니다.

이것이 i반대의 '번째 요소입니다 L. 비트 보수 ~i는와 같으 -i-1므로의 off-by-one 오류를 수정합니다 L[-i].


21

PEP448 – 추가 포장 풀기 일반화

Python 3.5 가 출시되면서 목록, 튜플, 세트 및 딕트의 조작이 골퍼가되었습니다.

iterable을 세트 / 목록으로 바꾸기

쌍을 비교하십시오 :

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

속는 (새로운하지만 더 upvotes을)
user202729
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.