คุณมีเคล็ดลับทั่วไปสำหรับการเล่นกอล์ฟใน Python อย่างไร ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟและอย่างน้อยก็ค่อนข้างเฉพาะเจาะจงกับ Python (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ)
กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คุณมีเคล็ดลับทั่วไปสำหรับการเล่นกอล์ฟใน Python อย่างไร ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟและอย่างน้อยก็ค่อนข้างเฉพาะเจาะจงกับ Python (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ)
กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คำตอบ:
ใช้แทนa=b=c=0
a,b,c=0,0,0
ใช้แทนa,b,c='123'
a,b,c='1','2','3'
เงื่อนไขอาจมีความยาว ในบางกรณีคุณสามารถแทนที่เงื่อนไขแบบง่าย(a,b)[condition]
ได้ หากcondition
เป็นจริงb
จะถูกส่งคืน
เปรียบเทียบ
if a<b:return a
else:return b
สำหรับสิ่งนี้
return(b,a)[a<b]
a if a<b else b
และa<b and a or b
(lambda(): b, lambda(): a)[a < b]()
ทำลัดวงจรของคุณเองด้วย lambdas
P and A or B
ของ A ใด ๆ bool(A)=False
ที่ทำให้ แต่(P and [A] or [B])[0]
จะทำหน้าที่ ดูdiveintopython.net/power_of_introspection/and_or.htmlสำหรับการอ้างอิง
สิ่งที่ยอดเยี่ยมที่ฉันเคยทำครั้งเดียวคือ:
if 3 > a > 1 < b < 5: foo()
แทน:
if a > 1 and b > 1 and 3 > a and 5 > b: foo()
ตัวดำเนินการเปรียบเทียบของ Python ร็อค
การใช้สิ่งนั้นเปรียบได้กับ Python 2 คุณสามารถหลีกเลี่ยงตัวand
ดำเนินการนี้ได้ ตัวอย่างเช่นถ้าa
, b
, c
และd
เป็นจำนวนเต็ม
if a<b and c>d:foo()
สามารถย่อให้สั้นลงโดยอักขระหนึ่งตัวไปที่:
if a<b<[]>c>d:foo()
สิ่งนี้ใช้ว่าทุกรายการมีขนาดใหญ่กว่าจำนวนเต็มใด ๆ
หากc
และd
เป็นรายการสิ่งนี้จะดีขึ้นกว่าเดิม:
if a<b<c>d:foo()
3>a>1<b<5
[$a => $b]->[$b <= $a]
:)
if(a<b)+(c>d):foo()
*
ที่ควรจะเป็น or
จะเป็น+
foo()if 3>a>1<b<5
หากคุณกำลังใช้ฟังก์ชั่นในตัวซ้ำ ๆ อาจเป็นพื้นที่ที่มีประสิทธิภาพมากขึ้นในการตั้งชื่อใหม่หากใช้อาร์กิวเมนต์ที่ต่างกัน:
r=range
for x in r(10):
for y in r(100):print x,y
บางครั้งรหัส Python ของคุณกำหนดให้คุณมีการเยื้อง 2 ระดับ สิ่งที่ชัดเจนที่ต้องทำคือใช้ช่องว่างหนึ่งและสองช่องสำหรับแต่ละระดับของการย่อหน้า
อย่างไรก็ตาม Python 2 พิจารณาว่าแท็บและอักขระเว้นวรรคเป็นระดับการเยื้องที่แตกต่างกัน
ซึ่งหมายความว่าระดับการเยื้องครั้งแรกสามารถเป็นหนึ่งช่องว่างและระดับที่สองสามารถเป็นหนึ่งอักขระแท็บ
ตัวอย่างเช่น:
if 1:
if 1:
\tpass
\t
อักขระแท็บอยู่ที่ไหน
TabError: inconsistent use of tabs and spaces in indentation.
ใช้การแทนที่สตริงและ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
สำหรับตัวเลือกทั้งสามนี้เราจะเห็นว่า:
exec"..."%(('lambda ',)*5)
จะบันทึก 2 ไบต์และเป็นตัวเลือกที่ดีที่สุดของคุณ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)
ครั้งในรหัสของคุณคุณก็ยังดีเขียน
replace
มาก
=>
= lambda
ยกตัวอย่างเช่นจะเป็นf=>:0
f = lambda: 0
ใช้การแบ่งส่วนเพิ่มเติมเพื่อเลือกหนึ่งสตริงจากหลาย ๆ สตริง
>>> 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
ในกรณีที่สองสตริงบูลีนนี้หนึ่งสามารถเขียน
b*"string"or"other_string"
สำหรับ
["other_string","string"][b]
ซึ่งแตกต่างจาก interleaving สิ่งนี้ใช้ได้กับสตริงที่มีความยาวเท่าใดก็ได้ แต่อาจมีปัญหาที่สำคัญกว่าตัวดำเนินการหากb
เป็นนิพจน์แทน
for x in ("foo","bar","baz"): print x
x
แสดงผล ส่วน golfed คือ"fbboaaorz"[x::3]
vs ["foo","bar","baz"][x]
วิธีที่x
ได้รับค่าจะเป็นอีกส่วนหนึ่งของการแก้ปัญหากอล์ฟของคุณ
ใช้`n`
เพื่อแปลงจำนวนเต็มเป็นสตริงแทนที่จะใช้str(n)
:
>>> n=123
>>> `n`
'123'
สมมติว่าคุณต้องการที่จะ hardcode 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
เท่ากับไปFalse
True
แนวคิดคือหมายเลขมายากลเก็บตารางเป็น bitstring bin(3714)
= 0b111010000010
โดยมีตัวเลขn
-th (จากท้าย) ตรงกับn
รายการตารางที่ เราเข้าถึงn
รายการ TH โดย bitshifting จำนวนช่องว่างที่เหมาะสมและการใช้หลักสุดท้ายโดยn
&1
วิธีการเก็บรักษานี้มีประสิทธิภาพมาก เปรียบเทียบกับทางเลือกอื่น
n in[1,7,9,10,11]
'0111010000010'[n]>'0'
คุณสามารถมีตารางการค้นหาที่เก็บหลายรายการที่สามารถแยกได้เช่น
340954054>>4*n&15
เพื่อแยกบล็อกสี่บิตที่เกี่ยวข้อง
สมมติว่าคุณวนซ้ำเซลล์ของm*n
กริด แทนที่จะเป็นสองfor
วงซ้อนกันสองวงหนึ่งแถวและหนึ่งคอลัมน์โดยปกติแล้วจะสั้นกว่าเมื่อใช้วงเดียวเพื่อวนซ้ำไปยังm*n
เซลล์ของตาราง คุณสามารถแยกแถวและคอลัมน์ของเซลล์ภายในลูป
รหัสเดิม:
for i in range(m):
for j in range(n):
do_stuff(i,j)
รหัส Golfed:
for k in range(m*n):
do_stuff(k/n,k%n)
ผลที่คุณกำลังทำซ้ำมากกว่าผลิตภัณฑ์ Cartesian ของทั้งสองช่วงการเข้ารหัสทั้งคู่เป็น(i,j)
x=i*n+j
คุณได้บันทึกการrange
โทรที่มีค่าใช้จ่ายและระดับของการเยื้องในลูป ลำดับของการวนซ้ำไม่เปลี่ยนแปลง
ใช้//
แทน/
ในหลาม 3. ถ้าคุณอ้างถึงi
และj
หลายครั้งก็อาจจะได้เร็วขึ้นในการกำหนดค่าของพวกเขาi=k/n
, j=k%n
ภายในวง
for i in range(m*n*o): do_stuff(i/n/o,i%(n*o)/o,i%o)
n
ลูป: repl.it/EHwa
itertools.product
สามารถรัดกุมมากกว่าลูปซ้อนโดยเฉพาะเมื่อสร้างผลิตภัณฑ์คาร์ทีเซียน a1, a2, b1, b2
เป็นตัวอย่างของผลิตภัณฑ์คาร์ทีเซียนของ'ab'
และ'12'
เว้นแต่โทเค็นต่อไปนี้เริ่มต้นด้วยหรือe
E
คุณสามารถลบช่องว่างตามหมายเลข
ตัวอย่างเช่น
if i==4 and j==4:
pass
กลายเป็น:
if i==4and j==4:
pass
การใช้สิ่งนี้ในข้อความสั่งบรรทัดเดียวที่ซับซ้อนสามารถบันทึกอักขระได้ไม่กี่ตัว
แก้ไข: ตามที่ @marcog ชี้ให้เห็นว่า4or a
จะใช้งานได้ แต่ไม่ใช่a or4
เมื่อสิ่งนี้สับสนกับชื่อตัวแปร
if(i,j)==(4,4):
สั้นลงและในกรณีพิเศษนี้if i==j==4:
4or a
งานได้ แต่ไม่ใช่a or4
0or
ยังไม่ทำงาน ( 0o
เป็นคำนำหน้าสำหรับหมายเลขฐานแปด)
0 or x
จะกลับมาx
เสมอ อาจจะถูกตัดออก0 or
ไป
0or
เป็นเรื่องปกติเนื่องจากเป็นส่วนหนึ่งของจำนวนที่นานกว่า เทียบเท่ากับ10 or x
10or x
สำหรับจำนวนเต็ม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
ผู้ประกอบการ~
และเอก-
มีความสำคัญสูงกว่า*
, /
, ซึ่งแตกต่างจากไบนารี%
+
-~-x
(1-x)
a+b+1
สามารถเขียนได้กระชับa-~b
กว่า
n-i-1
n+~i
วิธีที่ดีในการแปลง 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'
*s,='abcde'
แล้วs
ขัดข้อง python3 แบบโต้ตอบของฉันด้วย segfault :(
[*'abcde']
และถ้าคุณทำเช่นนี้ในการแสดงออกที่คุณสามารถทำได้
แทนที่จะ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
ดังนั้นเคล็ดลับนี้ควรใช้เฉพาะเมื่อไม่มีตัวเลือก
[1]*8
สั้นกว่าrange(8)
คุณยังประหยัดพื้นที่เพราะfor i in[...
ถูกกฎหมายในขณะที่for i in range...
ไม่ถูกต้อง"
exec"pass;"*8
สั้นกว่ามาก
r=1
, r*8
8, และคุณไม่สามารถย้ำผ่านหมายเลข ฉันเดาว่าคุณหมายถึงr=[1]
คุณสามารถใช้รูปหน้ายิ้มเอเลี่ยนตัวเก่าเพื่อย้อนกลับลำดับ:
[1, 2, 3, 4][::-1] # => [4, 3, 2, 1]
วิธีที่ดีที่สุดในการอธิบายสิ่งนี้คือผ่านตัวอย่าง:
>>> a,*b,c=range(5)
>>> a
0
>>> b
[1, 2, 3]
>>> c
4
เราได้เห็นการใช้งานนี้แล้ว - เปลี่ยน iterable เป็นรายการใน 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=[]
หลายครั้ง มันวิเศษมากที่คุณสามารถบันทึกตัวอักษรลงบนสิ่งที่ตรงไปตรงมาเช่นนี้
a,*L=1,
) แต่ก็ยังช่วยประหยัดถ่านหนึ่ง :)
a,*_,b=L
คุณสามารถเขียนชุดเช่นนี้S={1,2,3}
ซึ่งหมายความว่าคุณสามารถตรวจสอบการเป็นสมาชิกโดยใช้{e}&S
แทนการe in S
บันทึกอักขระหนึ่งตัว
if
ฐานะไม่มีช่องว่าง ( if{e}&S:
)
not in
โดย{e}-S
มีเคล็ดลับที่
สำหรับทุกวัยมันทำให้ฉันรำคาญที่ฉันไม่สามารถคิดถึงวิธีสั้น ๆ ในการรับตัวอักษรทั้งหมด หากคุณใช้range
เพียงพอที่R=range
มีค่าในโปรแกรมของคุณแล้ว
[chr(i+97)for i in R(26)]
สั้นกว่าความไร้เดียงสา
'abcdefghijklmnopqrstuvwxyz'
แต่อย่างอื่นมันมีความยาวมากกว่าตัวอักษรตัวเดียว มันหลอกหลอนฉันว่าคนฉลาดที่ต้องการความรู้เกี่ยวกับคุณค่าของ ASCII นั้นจบลงด้วยความละเอียดมากกว่าแค่พิมพ์ตัวอักษรทั้งหมด
จนกระทั่งผมเห็นนี้คำตอบสำหรับลูกสาวของฉันตัวอักษร ฉันไม่สามารถติดตามประวัติการแก้ไขได้ดีพอที่จะคิดได้ว่าอัจฉริยะนี้เป็นผลงานของ OP หรือถ้าเป็นคำแนะนำจากผู้แสดงความคิดเห็น แต่นี่คือ (ฉันเชื่อ) วิธีที่สั้นที่สุดในการสร้างตัวอักษร 26 ตัวที่น่าสนใจ ในอักษรโรมัน
map(chr,range(97,123))
หากกรณีไม่สำคัญคุณสามารถตัดอักขระอื่นโดยใช้ตัวพิมพ์ใหญ่
map(chr,range(65,91))
ฉันใช้map
วิธีมากเกินไปฉันไม่รู้ว่าสิ่งนี้ไม่เคยเกิดขึ้นกับฉัน
string.lowercase
- นั่นคือสิ่งที่มันมีไว้สำหรับ
ord('z')
) นอกเหนือจากมันเป็นระยะเวลาเดียวกัน ... นอกจากนี้ถ้าคุณต้องการ Alphanumerics แทนstr.isalpha
ในรุ่นของ @ quintopia str.isalnum
กับ (แต่ถ้าคุณต้องการเพียงหนึ่งกรณีสตริง 36 อักขระทั้งหมดไม่เกินfilter(str.isalnum,map(chr,range(90)))
)
R
รุ่นของฉันจะสั้นกว่าเดิมของคุณ: '%c'*26%tuple(R(97,123))
(เพียง 24 ตัวอักษร) ถ้าคุณสะกดrange
มันเป็นเพียงตราบใดที่ตัวอักษร - รุ่นตัวพิมพ์ใหญ่จะสั้นกว่า
แม้ว่าหลามจะไม่มีคำสั่งสลับคุณสามารถเลียนแบบพวกเขาด้วยพจนานุกรม ตัวอย่างเช่นหากคุณต้องการสวิตช์แบบนี้:
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)
dict(s1=v1,s2=v2,...,sn=vn)
แทนการ{'s1':v1,'s2':v2,...,'sn':vn}
บันทึก 2 * n-4 ไบต์และจะดีกว่าถ้า n> = 3
เมื่อคุณมีสองค่าบูลีนa
และb
ถ้าคุณต้องการที่จะหาถ้าทั้งสองa
และb
เป็นจริงใช้*
แทนand
:
if a and b: #7 chars
VS
if a*b: #3 chars
ถ้าค่าใดค่าหนึ่งเป็นเท็จมันจะประเมินดังเช่น0
ในคำสั่งนั้นและค่าจำนวนเต็มจะเป็นจริงเฉพาะในกรณีที่ไม่ใช่ค่าศูนย์
&
: a=b=False
,a&b
+
สำหรับor
หากคุณสามารถรับประกันได้a != -b
|
ทำงานได้ในทุกสถานการณ์
*
แทนand
/ &&
บันทึกบางไบต์ในหลายภาษา
Python 2 ช่วยให้คุณแปลงวัตถุx
เป็นตัวแทนสตริง`x`
ได้ด้วยราคาเพียง 2 ตัวอักษร ใช้สิ่งนี้สำหรับงานที่ทำได้ง่ายกว่าบนสตริงของวัตถุมากกว่าวัตถุ
เข้าร่วมตัวละคร
รับรายชื่อตัวละครl=['a','b','c']
หนึ่งสามารถสร้าง''.join(l)
เป็น`l`[2::5]
ซึ่งบันทึกไบต์
เหตุผลก็`l`
คือ "['a', 'b', 'c']"
(พร้อมช่องว่าง) เพื่อให้หนึ่งสามารถแยกตัวอักษรที่มีชิ้นรายการเริ่มต้นที่ตัวอักษรศูนย์ zeroed ตัวที่สองa
และนำตัวละครที่ห้าทุกจากที่นั่น '\n'
นี้ไม่ได้ทำงานที่จะเข้าร่วมสตริงหลายตัวละครหรือตัวหนีตัวแทนเช่น
เชื่อมโยงตัวเลข
ในทำนองเดียวกันการกำหนดรายการที่ไม่ว่างเปล่าของตัวเลขเช่นl=[0,3,5]
หนึ่งสามารถเชื่อมให้เป็นสตริงเป็น'035'
`l`[1::3]
map(str,l)
นี้ช่วยประหยัดทำสิ่งที่ต้องการ โปรดทราบว่าพวกเขาจะต้องหลักเดียวและไม่สามารถมีลอยเหมือน1.0
ผสม. นอกจากนี้ล้มเหลวในรายการที่ว่างเปล่า, ]
การผลิต
ตรวจสอบเชิงลบ
ตอนนี้สำหรับงานที่ไม่ใช่สตริง สมมติว่าคุณมีรายการl
ตัวเลขจริงและต้องการทดสอบว่ามีจำนวนลบใด ๆ หรือไม่สร้างบูลีน
คุณทำได้
'-'in`l`
ซึ่งตรวจสอบเครื่องหมายลบในตัวแทนสตริง นี้สั้นกว่าอย่างใดอย่างหนึ่ง
any(x<0for x in l)
min(l+[0])<0
สำหรับครั้งที่สองmin(l)<0
จะล้มเหลวในรายการว่างดังนั้นคุณต้องป้องกันความเสี่ยง
str(l)[2::5]
12 ไบต์เมื่อเทียบกับ ''.join(map(str,l))
19 สถานการณ์จริงที่เกิดขึ้น (ซึ่งl
เป็นคำสั่งเครื่องกำเนิดไม่รายการ) บันทึกฉันเพียงหนึ่งไบต์ ... ซึ่งยังคงคุ้มค่า!
ฟังก์ชั่นหนึ่งบรรทัดสามารถทำได้ด้วยแลมบ์ดา:
def c(a):
if a < 3: return a+10
else: return a-5
สามารถแปลงเป็น (หมายเหตุช่องว่างที่ขาดหายไป3and
และ10or
)
c=lambda a:a<3and a+10or a-5
c=lambda a:a+[-5,10][a<3]
หรือ และ / หรือเคล็ดลับมีประโยชน์มากขึ้นเมื่อคุณขึ้นอยู่กับพฤติกรรม
else:
สามารถลดลงได้เมื่อreturn
หยุดการทำงานของฟังก์ชั่นดังนั้นทุกอย่างที่ตามมาจะถูกดำเนินการเฉพาะในกรณีที่if
เงื่อนไขล้มเหลวหรือหาก else
เงื่อนไขเป็นจริง ดังนั้นelse
สามารถ ommited อย่างปลอดภัย (อธิบายโดยละเอียดสำหรับ
c=lambda a:a-5+15*(a<3)
การวนซ้ำสูงสุด 4 รายการอาจเป็นการดีกว่าที่จะจัดหา tuple แทนที่จะใช้ช่วง
for x in 0,1,2:
VS
for x in range(3):
หากคุณต้องการรับผลการปัดเศษสำหรับการแบ่งเช่นเดียวกับที่คุณทำกับ//
พื้นคุณสามารถใช้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
n//1+1
แทนที่จะเป็น ceil แต่มันหมายถึง ceil (n) = n + 1 แต่มันควรใช้ได้กับค่าที่ไม่ใช่จำนวนเต็มทั้งหมด
round(x)
คือ(x+.5)//1
+1 ไบต์ แต่หลังเริ่มต้นด้วย a (
และถ้าx
เป็นผลรวมประกอบด้วยค่าคงที่จะมีประโยชน์
+=
แทนappend
และextend
A.append(B)
สามารถย่อให้เหลือ:
A+=B,
B,
ที่นี่สร้าง tuple หนึ่งองค์ประกอบที่สามารถนำมาใช้ในการขยายA
เช่นเดียวกับใน[B]
A+=[B]
A.extend(B)
สามารถย่อให้เหลือ:
A+=B
return 0
หรือreturn 1
เทียบเท่ากับหรือreturn False
return True
-x
มากกว่า หรือเพียงแค่...x*-1
--8.32
-8.32*-1
8.32
A+=B
B
tuple
เลือกหนึ่งในสองตัวเลขตามเงื่อนไข
คุณรู้แล้วว่าใช้การเลือกรายการ[x,y][b]
ด้วย Boolean b
สำหรับนิพจน์ประกอบy if b else x
ไปด้วย ตัวแปรx
, y
และ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
เพื่อให้ปฏิเสธได้
หากL
เป็นรายการให้ใช้L[~i]
เพื่อรับi
องค์ประกอบ 'จากด้านหลัง
นี่คือ'องค์ประกอบของวันกลับของi
L
บิตสมบูรณ์~i
เท่ากับและเพื่อแก้ไขข้อผิดพลาดออกโดยหนึ่งจาก -i-1
L[-i]
ด้วยการเปิดตัวPython 3.5 การจัดการรายการ tuples ชุดและ dicts ก็จะกลายเป็นนักกอล์ฟ
เปรียบเทียบคู่:
set(T)
{*T}
list(T)
[*T]
tuple(T)
(*T,)
สั้นกว่ามาก! แต่โปรดทราบว่าถ้าคุณเพียงต้องการที่จะแปลงบางสิ่งบางอย่างไปยังรายการและกำหนดให้ตัวแปรปกติขยายการเปิดออก iterableสั้น:
L=[*T]
*L,=T
ไวยากรณ์ที่คล้ายกันใช้ได้กับสิ่งอันดับ:
T=*L,
ซึ่งเหมือนกับขยาย iterable ขยาย แต่ด้วยเครื่องหมายดอกจันและเครื่องหมายจุลภาคในด้านอื่น ๆ
การคลายไฟล์จะสั้นกว่าการต่อข้อมูลเล็กน้อยหากคุณต้องการผนวก list / tuple ไว้ทั้งสองด้าน:
[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
นี้โดยทั่วไปจะขัดแย้งกับความจำเป็นในการใด ๆ
เปลี่ยนimport *
เป็นimport*
หากคุณไม่เคยได้ยินให้import*
บันทึกตัวอักษร!
from math import*
มีความยาวมากกว่า 1 อักขระimport math as m
และคุณจะลบอินสแตนซ์ทั้งหมดของm.
แม้แต่การใช้เพียงครั้งเดียวก็ช่วยได้!
>>> for i in range(x):s+=input()
ถ้าคุณค่าของฉันไม่มีประโยชน์:
>>> for i in[0]*x:s+=input()
หรือ
>>> exec's+=input();'*x
for i in[0]*x:s+=input()
บันทึกพื้นที่อื่น นอกจากนี้คุณสามารถลบช่องว่างระหว่าง exec และเครื่องหมายคำพูดแรกที่จะได้รับexec's+=input();'*x
for i in[0]*x:s+=input()