ในงูหลามฉันจะทำสิ่งที่ชอบ:
for car in cars:
# Skip first and last, do work for rest
ในงูหลามฉันจะทำสิ่งที่ชอบ:
for car in cars:
# Skip first and last, do work for rest
คำตอบ:
คำตอบอื่น ๆ ใช้สำหรับลำดับเท่านั้น
สำหรับทุก ๆ iterable ข้ามรายการแรก:
itercars = iter(cars)
next(itercars)
for car in itercars:
# do work
หากคุณต้องการข้ามสิ่งสุดท้ายคุณสามารถทำได้:
itercars = iter(cars)
# add 'next(itercars)' here if you also want to skip the first
prev = next(itercars)
for car in itercars:
# do work on 'prev' not 'car'
# at end of loop:
prev = car
# now you can do whatever you want to do to the last one on 'prev'
หากต้องการข้ามองค์ประกอบแรกใน Python คุณสามารถเขียนได้
for car in cars[1:]:
# Do What Ever you want
หรือข้าม elem สุดท้าย
for car in cars[:-1]:
# Do What Ever you want
คุณสามารถใช้แนวคิดนี้เพื่อลำดับใดก็ได้
วิธีที่ดีที่สุดในการข้ามรายการแรกคือ:
from itertools import islice
for car in islice(cars, 1, None):
# do something
islice ในกรณีนี้ถูกเรียกใช้โดยมีจุดเริ่มต้นที่ 1 และจุดสิ้นสุดที่ไม่มีซึ่งแสดงถึงจุดสิ้นสุดของตัววนซ้ำ
เพื่อให้สามารถข้ามรายการจากจุดสิ้นสุดของการทำซ้ำคุณต้องทราบความยาวของมัน (เป็นไปได้เสมอสำหรับรายการ แต่ไม่จำเป็นสำหรับทุกสิ่งที่คุณสามารถทำซ้ำได้) ตัวอย่างเช่น islice (รถยนต์, 1, len (รถยนต์) -1) จะข้ามรายการแรกและสุดท้ายในรายการรถยนต์
isliceค่อนข้างดีโดยไม่ทราบความยาวหรือเก็บรายการเพิ่มเติมในหน่วยความจำในครั้งเดียวเกินความจำเป็นอย่างแน่นอน
isliceคือสิ่งที่ถูกส่งผ่านไปยังdequeไม่ใช่ตัววนซ้ำทั้งหมดและเป็นเพียงความยาวของจำนวนรายการที่จะข้ามเมื่อสิ้นสุด มันไม่ได้เก็บตัววนซ้ำทั้งหมดไว้ในหน่วยความจำ
นี่คือฟังก์ชั่นเครื่องกำเนิดทั่วไปที่ข้ามรายการจำนวนใด ๆ ตั้งแต่เริ่มต้นและสิ้นสุดการทำซ้ำ:
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
for x in itertools.islice(it, at_start):
pass
queue = collections.deque(itertools.islice(it, at_end))
for x in it:
queue.append(x)
yield queue.popleft()
ตัวอย่างการใช้งาน:
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
at_end == 0อาจต้องการเพิ่มเส้นทางได้อย่างรวดเร็วสำหรับ
skip(xrange(10000000), 1)จะใช้at_end=0ดังนั้นพารามิเตอร์ที่deque()จะเป็นislice(it, 0)ซึ่งจะใช้องค์ประกอบเป็นศูนย์itเท่านั้น สิ่งนี้จะไม่ใช้หน่วยความจำมาก
for item in do_not_use_list_as_a_name[1:-1]:
#...do whatever
listเป็นชื่อตัวแปร
listสามารถถูกผูกใหม่ได้ นั่นเป็นเหตุผลที่คุณไม่ควรมากกว่าไม่สามารถใช้งานได้
ตามคำตอบของ @SvenMarnach แต่บิตง่ายขึ้นและไม่ต้องใช้ deque
>>> def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
it = itertools.islice(it, at_start, None)
it, it1 = itertools.tee(it)
it1 = itertools.islice(it1, at_end, None)
return (next(it) for _ in it1)
>>> list(skip(range(10), at_start=2, at_end=2))
[2, 3, 4, 5, 6, 7]
>>> list(skip(range(10), at_start=2, at_end=5))
[2, 3, 4]
หมายเหตุด้วยจากtimeitผลลัพธ์ของฉันนี้จะเร็วกว่าการแก้ปัญหาเล็กน้อย
>>> iterable=xrange(1000)
>>> stmt1="""
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
it = itertools.islice(it, at_start, None)
it, it1 = itertools.tee(it)
it1 = itertools.islice(it1, at_end, None)
return (next(it) for _ in it1)
list(skip(iterable,2,2))
"""
>>> stmt2="""
def skip(iterable, at_start=0, at_end=0):
it = iter(iterable)
for x in itertools.islice(it, at_start):
pass
queue = collections.deque(itertools.islice(it, at_end))
for x in it:
queue.append(x)
yield queue.popleft()
list(skip(iterable,2,2))
"""
>>> timeit.timeit(stmt = stmt1, setup='from __main__ import iterable, skip, itertools', number = 10000)
2.0313770640908047
>>> timeit.timeit(stmt = stmt2, setup='from __main__ import iterable, skip, itertools, collections', number = 10000)
2.9903135454296716
tee()คุณยังคงสร้างรายการทั้งหมดในหน่วยความจำสำหรับเครื่องกำเนิดไฟฟ้าใช่ไหม (ของคุณit1)
ตัวอย่าง:
mylist=['one'.'two','three'.'four'.'five']
for i in mylist[1:]:
print(i)
ใน python index เริ่มต้นจาก 0 เราสามารถใช้โอเปอเรเตอร์ slicing เพื่อทำการเปลี่ยนแปลงในการวนซ้ำ
for i in range(1,-1):
ไวยากรณ์ของคุณไม่ใช่ Python ที่เริ่มต้นจริงๆ
ซ้ำในหลามมีมากกว่าเขาเนื้อหาของภาชนะบรรจุ (ดีในทางเทคนิคมันมากกว่า iterators) for item in containerกับไวยากรณ์ ในกรณีนี้คอนเทนเนอร์เป็นcarsรายการ แต่คุณต้องการข้ามองค์ประกอบแรกและครั้งสุดท้ายดังนั้นจึงหมายความว่าcars[1:-1](รายการหลามเป็นเลขศูนย์ลบจำนวนลบนับจากท้ายและ:มีการแบ่งไวยากรณ์
ดังนั้นคุณต้องการ
for c in cars[1:-1]:
do something with c
วิธีทางเลือก:
for idx, car in enumerate(cars):
# Skip first line.
if not idx:
continue
# Skip last line.
if idx + 1 == len(cars):
continue
# Real code here.
print car
นี่คือตัวเลือกที่ฉันต้องการ มันไม่ต้องการการเพิ่มในลูปมากและไม่ใช้อะไรนอกจากเครื่องมือในตัว
ไปจาก:
for item in my_items:
do_something(item)
ถึง:
for i, item in enumerate(my_items):
if i == 0:
continue
do_something(item)
หากcarsเป็นลำดับคุณสามารถทำได้
for car in cars[1:-1]:
pass
more_itertoolsโครงการขยายitertools.isliceที่จะจัดการกับดัชนีเชิงลบ
ตัวอย่าง
import more_itertools as mit
iterable = 'ABCDEFGH'
list(mit.islice_extended(iterable, 1, -1))
# Out: ['B', 'C', 'D', 'E', 'F', 'G']
ดังนั้นคุณสามารถใช้องค์ประกอบชิ้นอย่างหรูหราระหว่างรายการแรกและชิ้นสุดท้ายของ iterable:
for car in mit.islice_extended(cars, 1, -1):
# do something
ฉันทำแบบนี้แม้ว่าจะดูเหมือนว่าแฮ็คมันจะทำงานทุกครั้ง:
ls_of_things = ['apple', 'car', 'truck', 'bike', 'banana']
first = 0
last = len(ls_of_things)
for items in ls_of_things:
if first == 0
first = first + 1
pass
elif first == last - 1:
break
else:
do_stuff
first = first + 1
pass
for n, i in enumerate(cars): if n!= 0: do something to iไปแล้ว ตรรกะก็คือว่ามันจะเพิ่มเคาน์เตอร์if n == some_value'เพื่อแต่ละค่าซึ่งคุณสามารถกำหนดเป้าหมายเช่นกับ ในตัวอย่างนี้มันจะทำอะไรกับอินสแตนซ์ของฉันแต่ละตัวยกเว้นตัวแรก