ฉันจะหลีกเลี่ยงการประกาศตัวแปรที่ไม่ได้ใช้ใน for loop ได้อย่างไร


88

หากฉันมีความเข้าใจในรายการ (ตัวอย่าง) เช่นนี้:

['' for x in myList]

สร้างรายการใหม่ที่มีสตริงว่างสำหรับทุกองค์ประกอบในรายการได้อย่างมีประสิทธิภาพฉันไม่เคยใช้x. มีวิธีเขียนที่สะอาดกว่านี้หรือไม่โดยที่ฉันไม่ต้องประกาศxตัวแปรที่ไม่ได้ใช้


ได้รับแรงบันดาลใจจากคำถามนี้ฉันสร้างบทช่วยสอน youtube ที่ครอบคลุมตัวแปรที่ไม่ได้ใช้ในความเข้าใจของรายการ youtube.com/watch?v=cZb5aFcpsAs
Brendan Metcalfe

คำตอบ:


132

_ เป็นชื่อตัวยึดมาตรฐานสำหรับสมาชิกที่ถูกละเว้นในการกำหนด for-loop และ tuple เช่น

['' for _ in myList]

[a+d for a, _, _, d, _ in fiveTuples]

BTW รายการของคุณสามารถเขียนได้โดยไม่มีความเข้าใจในรายการ (สมมติว่าคุณต้องการสร้างรายชื่อสมาชิกที่ไม่เปลี่ยนรูปเช่นสตริงจำนวนเต็ม ฯลฯ )

[''] * len(myList)

10
หลังจะต้องมาพร้อมกับคำเตือนขนาดใหญ่ว่าจะไม่ทำสิ่งที่คาดไว้สำหรับวัตถุที่เปลี่ยนแปลงไม่ได้

5
@Mohit:a=[[]]*4;a[0].append(5);print(a)
kennytm

@Ramy: Mohit โพสต์คำอธิบาย แต่มันก็ลบ: S อย่างไรก็ตามตรวจสอบหมายเหตุ 2 ในdocs.python.org/py3k/library/...
kennytm

2
@Ramy, Python เก็บข้อมูลอ้างอิงเดียวกันสำหรับวัตถุเดียวกันในหน่วยความจำ
Mohit Ranka

มีความสำคัญหรือไม่ถ้าฉันกำลังทำforลูปแบบซ้อนกัน หรือถ้าข้างในfor _ in range(...)อยากบอก_, var = f(x)? มันจะสับสนระหว่างสอง_ตัวแปรหรือไม่?
Eric Auld

19

ไม่ตามที่เซนกล่าวไว้: กรณีพิเศษไม่พิเศษพอที่จะทำลายกฎ กรณีพิเศษคือการวนซ้ำโดยไม่ใช้รายการของสิ่งที่ถูกทำซ้ำและกฎคือมี "เป้าหมาย" ที่จะแกะกล่อง

อย่างไรก็ตามคุณสามารถใช้_เป็นชื่อตัวแปรซึ่งโดยปกติจะเข้าใจว่า "ไม่ได้ใช้โดยเจตนา" (แม้แต่ PyLint ฯลฯ ก็รู้และเคารพสิ่งนี้)


อย่างไรก็ตาม PyLint บ่นว่าC: 10,24: Invalid variable name "_" (invalid-name)เว้นแต่คุณจะเพิ่มลงgood-namesใน.pylintrcไฟล์.
giorgiosironi

13

ปรากฎว่าใช้dummy*(เริ่มต้นคำจำลอง) _เป็นชื่อตัวแปรไม่หลอกลวงเช่นเดียวกับ _เป็นมาตรฐานที่รู้จักกันดีและควรใช้ชื่อตัวแปรที่มีความหมายดีกว่า ดังนั้นคุณสามารถใช้dummy, ,dummy1 dummy_anythingการใช้ชื่อตัวแปรเหล่านี้PyLintจะไม่บ่น


ฉันชอบแนวทางนี้มากกว่า มันยังคงมีความหมาย
RvdK

2

เพิ่มความคิดเห็นต่อไปนี้หลัง for loop ในบรรทัดเดียวกัน:

#pylint: ปิดการใช้งาน = ตัวแปรที่ไม่ได้ใช้

for i in range(100): #pylint: disable=unused-variable

1

หากคุณต้องการตั้งชื่ออาร์กิวเมนต์ของคุณ (ในกรณีเช่นเมื่อเขียนล้อเลียนที่ไม่ใช้อาร์กิวเมนต์บางตัวที่อ้างอิงตามชื่อ) คุณสามารถเพิ่มวิธีการทางลัดนี้:

def UnusedArgument(_):
  pass

แล้วใช้แบบนี้

def SomeMethod(name_should_remain):
  UnusedArgument(name_should_remain)

0

วัตถุเครื่องกำเนิดไฟฟ้าไม่ได้ใช้ตัวแปรจริงๆ ดังนั้นสิ่งที่ชอบ

list(('' for x in myList))

ควรทำเคล็ดลับ โปรดทราบว่า x ไม่ได้ถูกกำหนดให้เป็นตัวแปรนอกความเข้าใจของเครื่องกำเนิดไฟฟ้า


0

คุณยังสามารถนำหน้าชื่อตัวแปรได้ด้วย_หากคุณต้องการให้ตัวแปรเป็นชื่อที่มนุษย์อ่านได้ ตัวอย่างเช่นคุณสามารถใช้_foo, _foo1, _anythingและ PyLint จะไม่บ่น ในวงรอบมันจะเป็นดังนี้:

for _something in range(10):
    do_something_else()

แก้ไข: เพิ่มตัวอย่าง


0

วิธี verbose คือ:

newList = []
while len(newList) < len(mylist):
    newList.append('')

คุณหลีกเลี่ยงการประกาศตัวแปรที่ใช้ด้วยวิธีนี้

นอกจากนี้คุณสามารถผนวกทั้งวัตถุที่ไม่แน่นอนและไม่เปลี่ยนรูป (เช่นพจนานุกรม) newListลง

อีกอย่างสำหรับมือใหม่ python อย่างฉัน '_', 'dummy' ค่อนข้างอึกอัก



-1

แสดงความคิดเห็นต่อฉันจะหลีกเลี่ยงการประกาศตัวแปรที่ไม่ได้ใช้ใน for loop ได้อย่างไร? (ขนาดความคิดเห็นหมด)

Python เก็บข้อมูลอ้างอิงเดียวกันสำหรับวัตถุที่สร้างขึ้น (โดยไม่คำนึงถึงความผันแปร) ตัวอย่างเช่น

In [1]: i = 1

In [2]: j = 1

In [3]: id(i)
Out[3]: 142671248

In [4]: id(j)
Out[4]: 142671248

คุณสามารถเห็นทั้ง i และ j อ้างถึงวัตถุเดียวกันในหน่วยความจำจะเกิดอะไรขึ้นเมื่อเราเปลี่ยนค่าของตัวแปรที่ไม่เปลี่ยนรูป

In [5]: j = j+1

In [6]: id(i)
Out[6]: 142671248

In [7]: id(j)
Out[7]: 142671236

คุณสามารถเห็น j เริ่มชี้ตำแหน่งใหม่แล้ว (โดยที่ 2 ถูกเก็บไว้) และฉันยังคงชี้ไปยังตำแหน่งที่ 1 ถูกเก็บไว้ ในขณะที่ประเมิน

j = j+1

ค่าจะถูกเลือกจาก 142671248 คำนวณ (หากยังไม่ได้แคช) และวางที่ตำแหน่งใหม่ 142671236 j ถูกสร้างขึ้นเพื่อชี้ไปยังตำแหน่งใหม่ ในแง่ที่ง่ายกว่าคือการทำสำเนาใหม่ทุกครั้งที่มีการแก้ไขตัวแปรที่ไม่เปลี่ยนรูป

ความไม่แน่นอน

วัตถุที่เปลี่ยนแปลงไม่ได้ทำหน้าที่แตกต่างกันเล็กน้อยในเรื่องนี้ เมื่อค่าชี้โดย

In [16]: a = []

In [17]: b = a

In [18]: id(a)
Out[18]: 3071546412L

In [19]: id(b)
Out[19]: 3071546412L

ทั้ง a และ b ชี้ไปที่ตำแหน่งหน่วยความจำเดียวกัน

In [20]: a.append(5)

ตำแหน่งหน่วยความจำที่ชี้โดย a ถูกแก้ไข

In [21]: a
Out[21]: [5]

In [22]: b
Out[22]: [5]

In [23]: id(a)
Out[23]: 3071546412L

In [24]: id(b)
Out[24]: 3071546412L

ทั้ง a และ b ยังคงชี้ไปที่ตำแหน่งหน่วยความจำเดียวกัน กล่าวอีกนัยหนึ่งตัวแปรที่เปลี่ยนแปลงได้ทำหน้าที่ในตำแหน่งหน่วยความจำเดียวกันที่ชี้โดยตัวแปรแทนที่จะทำสำเนาของค่าที่ตัวแปรชี้ไปเช่นในกรณีตัวแปรที่ไม่เปลี่ยนรูป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.