วิธีการระบุช่วงของตัวเลขเริ่มต้นที่ 1


154

ฉันใช้ Python 2.5 ฉันต้องการนับเช่นนี้ (เริ่มต้นที่ 1 แทนที่จะเป็น 0):

[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

ฉันรู้ใน Python 2.6 คุณสามารถทำได้: h = แจกแจง (ช่วง (2000, 2005), 1) เพื่อให้ผลลัพธ์ข้างต้น แต่ใน python2.5 คุณไม่สามารถ ...

ใช้ python2.5:

>>> h = enumerate(range(2000, 2005))
>>> [x for x in h]
[(0, 2000), (1, 2001), (2, 2002), (3, 2003), (4, 2004)]

ไม่มีใครรู้วิธีที่จะได้รับผลลัพธ์ที่ต้องการในหลาม 2.5?

ขอบคุณ

เจฟฟ์


4
แค่อยากรู้อยากเห็นเพราะฉันเป็นคนที่ไม่ได้ทำอะไรในทางของ Python อย่างมืออาชีพ คุณ จำกัด Python 2.5 เพียงเพราะ บริษัท ของคุณไม่ต้องการอัพเกรดด้วยเหตุผลด้านความเข้ากันได้?
Sean

2
เวอร์ชั่น 2.x ทั้งหมดใช้งานร่วมกันได้ย้อนหลังดังนั้นจึงไม่มีเหตุผล
Jochen Ritzel

บอกให้โมดูลบาง - มีไม่กี่คนที่ทำงานใน Py 2.5 แต่ไม่ใช่ Py 2.6
xorsyst

คำตอบ:


179

ดังที่คุณพูดไปแล้วสิ่งนี้เป็นเรื่องง่ายที่จะทำใน Python 2.6 หรือใหม่กว่า:

enumerate(range(2000, 2005), 1)

Python 2.5 และรุ่นที่เก่ากว่าไม่รองรับstartพารามิเตอร์ดังนั้นคุณสามารถสร้างวัตถุสองช่วงและแทนที่พวกเขา:

r = xrange(2000, 2005)
r2 = xrange(1, len(r) + 1)
h = zip(r2, r)
print h

ผลลัพธ์:

[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

หากคุณต้องการสร้างเครื่องกำเนิดไฟฟ้าแทนรายการคุณสามารถใช้izipแทน


ใช้งานizipและxrangeจะเข้าใกล้การแจกแจง
John La Rooy

7
คำตอบนี้ล้าสมัยคุณสามารถใส่enumerate(iterable, start=1)Python 2.6 ได้แล้ว
Fredrick Brennan

@frb: คุณอ่านคำถามหรือไม่ เขารู้วิธีแก้ปัญหาสำหรับ Python 2.6 แล้ว เขาถามหาวิธีแก้ปัญหาที่ทำงานใน Python 2.5 โดยเฉพาะ
Mark Byers

1
@ MarkByers เห็นได้ชัดว่าฉันตาบอด :) ขอโทษจริงๆเกี่ยวกับเรื่องนี้ (นี่คือ # 1 ใน Google สำหรับ "ระบุเริ่มต้นที่ 1")
Fredrick Brennan

2
@ 8chan อ๋อฉันเพิ่งได้รับที่นี่จากการค้นหาของ Google "ไม่ระบุเริ่มต้นจากศูนย์หลาม" :)
baxx

166

เพียงแค่ใส่ที่นี่เพื่อเห็นแก่ลูกหลานใน 2.6 พารามิเตอร์ "เริ่มต้น" ถูกเพิ่มเข้ามาเพื่อระบุเช่น:

enumerate(sequence, start=1)


26
โปรดทราบว่าสิ่งนี้จะไม่ข้ามรายการแรกในรายการ แต่จะชดเชยดัชนีด้วยค่าเริ่มต้นดังนั้นคุณจะได้รับอาร์เรย์ที่ไม่มีขอบเขตหากคุณทำสิ่งต่าง ๆ เช่น: sequence[i]ในรหัสของคุณ
phyatt

14

ง่ายเพียงแค่กำหนดฟังก์ชั่นของคุณเองซึ่งทำสิ่งที่คุณต้องการ:

def enum(seq, start=0):
    for i, x in enumerate(seq):
        yield i+start, x

12

Python 3

เอกสารอย่างเป็นทางการ: enumerate(iterable, start=0)

ดังนั้นคุณจะใช้มันเช่นนี้:

>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']

>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]

>>> list(enumerate(seasons, start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

10

วิธีที่ง่ายที่สุดใน Python 2.5 ที่คุณต้องการ:

import itertools as it

... it.izip(it.count(1), xrange(2000, 2005)) ...

หากคุณต้องการรายชื่อตามที่คุณดูเหมือนจะใช้แทนzipit.izip

(BTW ตามกฎทั่วไปวิธีที่ดีที่สุดในการสร้างรายชื่อออกมาจากเครื่องกำเนิดไฟฟ้าหรือ X ที่สามารถทำซ้ำได้อื่น ๆไม่ใช่ [x for x in X]แต่เป็นlist(X))


6
from itertools import count, izip

def enumerate(L, n=0):
    return izip( count(n), L)

# if 2.5 has no count
def count(n=0):
    while True:
        yield n
        n+=1

ตอนนี้ใช้h = list(enumerate(xrange(2000, 2005), 1))งานได้


6

แจงนับเป็นเรื่องไม่สำคัญและเป็นการนำมาใช้อีกครั้งเพื่อยอมรับการเริ่มต้น:

def enumerate(iterable, start = 0):
    n = start
    for i in iterable:
        yield n, i
        n += 1

โปรดทราบว่านี่จะไม่ทำลายรหัสโดยใช้การแจกแจงโดยไม่มีอาร์กิวเมนต์เริ่มต้น อีกทางหนึ่งผู้เผยแพร่รายนี้อาจสง่างามกว่าและเร็วกว่า แต่แบ่งการใช้งานอื่น ๆ

enumerate = ((index+1, item) for index, item)

หลังเป็นเรื่องไร้สาระที่บริสุทธิ์ @ Duncan ได้รับเสื้อคลุมด้านขวา


ใช่เรื่องไร้สาระทั้งหมด บางสิ่งบางอย่างตามแนวนี้จะใช้งานได้จริงเช่น Haskell (การปิดกั้นเป็นสิ่งที่เป็นธรรมชาติที่สุดในภาษานั้นและเนื่องจากความเกียจคร้านของฟังก์ชั่นการทำรายการจึงคล้ายกับนิพจน์กำเนิด แต่นั่นไม่ได้แก้ตัวฉัน - ผู้ใช้ python เป็นเวลานาน - เขียน BS ขอบคุณที่ชี้นำ

5
>>> list(enumerate(range(1999, 2005)))[1:]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

แจกแจงควรเป็นเครื่องกำเนิดไฟฟ้า สร้างรายการทั้งหมดในครั้งเดียวเพื่อย้ำถ้าไม่ยอมรับ
John La Rooy

ทั่วไป: start = 4 รายการ (แจกแจง (ช่วง (เริ่มต้น) + ช่วง (1999, 2005))) [start:]
Tony Veijalainen

อย่างไรก็ตามรายการอยู่ในช่วง 2.52
Tony Veijalainen

3

h = [(i + 1, x) for i, x in enumerate(xrange(2000, 2005))]


1
เขาทำสิ่งนี้ไม่ได้ใน Python 2.5 พารามิเตอร์เริ่มต้นเป็นที่รู้จักใน Python 2.6: docs.python.org/library/functions.html#enumerate เขายังกล่าวถึงสิ่งนี้ในคำถาม
Mark Byers

ตอบคำถามนี้ก่อนการแก้ไขครั้งแรกเมื่อรหัสไม่ฟอร์แมตและปัญหาดูเหมือนว่าฉันจะใช้เครื่องกำเนิดไฟฟ้าแทนรายการ
Chris B.

++: นั่นเป็นวิธีที่จะทำ
Nas Banov

2

ตกลงฉันรู้สึกบิตโง่นี่ ... สิ่งที่เป็นเหตุผลที่จะไม่เพียงแค่ทำมันกับสิ่งที่ต้องการ
[(a+1,b) for (a,b) in enumerate(r)]? หากคุณไม่ทำงานก็ไม่มีปัญหาเช่นกัน:

>>> r = range(2000, 2005)
>>> [(a+1,b) for (a,b) in enumerate(r)]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

>>> enumerate1 = lambda r:((a+1,b) for (a,b) in enumerate(r)) 

>>> list(enumerate1(range(2000,2005)))   # note - generator just like original enumerate()
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

1
>>> h = enumerate(range(2000, 2005))
>>> [(tup[0]+1, tup[1]) for tup in h]
[(1, 2000), (2, 2001), (3, 2002), (4, 2003), (5, 2004)]

เนื่องจากนี่ค่อนข้างละเอียดฉันขอแนะนำให้คุณเขียนฟังก์ชันของคุณเพื่อทำให้เป็นมาตรฐาน:

def enumerate_at(xs, start):
    return ((tup[0]+start, tup[1]) for tup in enumerate(xs))

2
แจกแจงควรเป็นเครื่องกำเนิดไฟฟ้า สร้างรายการทั้งหมดในครั้งเดียวเพื่อย้ำถ้าไม่ยอมรับ
John La Rooy

0

ฉันไม่ทราบว่าโพสต์เหล่านี้อาจมีความซับซ้อนมากขึ้นได้อย่างไรจากนั้นต่อไปนี้:

# Just pass the start argument to enumerate ...
for i,word in enumerate(allWords, 1):
    word2idx[word]=i
    idx2word[i]=word
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.