คุณมีเคล็ดลับทั่วไปสำหรับการเล่นกอล์ฟใน Python อย่างไร ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟและอย่างน้อยก็ค่อนข้างเฉพาะเจาะจงกับ Python (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ)
กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คุณมีเคล็ดลับทั่วไปสำหรับการเล่นกอล์ฟใน Python อย่างไร ฉันกำลังมองหาความคิดที่สามารถนำไปใช้กับปัญหารหัสกอล์ฟและอย่างน้อยก็ค่อนข้างเฉพาะเจาะจงกับ Python (เช่น "ลบความคิดเห็น" ไม่ใช่คำตอบ)
กรุณาโพสต์หนึ่งเคล็ดลับต่อคำตอบ
คำตอบ:
ใช้แทนa=b=c=0a,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เท่ากับไปFalseTrue
แนวคิดคือหมายเลขมายากลเก็บตารางเป็น 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 เช่น -~nn-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*88, และคุณไม่สามารถย้ำผ่านหมายเลข ฉันเดาว่าคุณหมายถึง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และextendA.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*-18.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-1L[-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()