简体   繁体   中英

how do I iterate only once per function call

I have a list of things I want to iterate over and return each of them only once per function call.

What I've tried:


tl = """
zza,zzb,zzc,zzd,zze,zzf,zzg,zzh,zzi,zzj,zzk,zzl,zzm,zzn,zzo,zzp,zzq,zzr,zzs,zzt,zzu,zzv,zzw,zzx,zzy,zzz
"""

# convert each string into list
result = [x.strip() for x in tl.split(",")]

index = 0

def func():
    return result[index]
    index += 1

It's saying code unreachable at the index += 1 part. The output I want is zza the first time I call func(), then zzb, then zzc, etc.

Appreciate the help.

EDIT: I've found this answer to work well and easily readable:

# list of elements seperated by a comma
tl = """
zza,zzb,zzc,zzd,zze,zzf,zzg,zzh,zzi,zzj,zzk,zzl,zzm,zzn,zzo,zzp,zzq,zzr,zzs,zzt,zzu,zzv,zzw,zzx,zzy,zzz
"""
# split each string by comma to get a list
result = [x.strip() for x in tl.split(",")]

# initialize the object
iterator_obj = iter(result)

print(next(iterator_obj))
print(next(iterator_obj))
print(next(iterator_obj))

output:

zza
zzb
zzc

In c++ there is an operator that will increment a variable with ++i incrementing before evaluation and i++ after evaluation

(i:=i+1) #same as ++i (increment, then return new value)
(i:=i+1)-1 #same as i++ (return the incremented value -1)

so the function you want is

def func():
    global index
    return result[(index := index+1)-1]

the := operator is new in python 3.8

so

tl = """
zza,zzb,zzc,zzd,zze,zzf,zzg,zzh,zzi,zzj,zzk,zzl,zzm,zzn,zzo,zzp,zzq,zzr,zzs,zzt,zzu,zzv,zzw,zzx,zzy,zzz
"""

# convert each string into list
result = [x.strip() for x in tl.split(",")]

index = 0

def func():
    global index
    return result[(index := index + 1) - 1]

print(func())
print(func())
print(func())
print(func())

prints

zza
zzb
zzc
zzd

Because return statement exit the function, any statement after that is not reachable. A quick fix to your code:

tl = """
zza,zzb,zzc,zzd,zze,zzf,zzg,zzh,zzi,zzj,zzk,zzl,zzm,zzn,zzo,zzp,zzq,zzr,zzs,zzt,zzu,zzv,zzw,zzx,zzy,zzz
"""

# convert each string into list
result = [x.strip() for x in tl.split(",")]

next_index = 0

def func():
    global next_index
    next_index += 1
    return result[next_index-1]

BTW, your func behaves like built-in next . If you don't want to reinvent the wheel:

# convert each string into iterator
result = (x.strip() for x in tl.split(","))
# next(result) will get to the next item on the list

If you want to be able to only return one item of your string at a time per function call, you need to use an generator:

def func(items):
    string_list = items.split(",")
    for i in range(len(string_list)):
        yield string_list[i]

tl = """
zza,zzb,zzc,zzd,zze,zzf,zzg,zzh,zzi,zzj,zzk,zzl,zzm,zzn,zzo,zzp,zzq,zzr,zzs,zzt,zzu,zzv,zzw,zzx,zzy,zzz
"""

item = func(tl)

To pull a value out, in order, use

next(item) # zza
next(item) # zzb
...

Every time you call next , a new value will be returned.

As an aside, anything after return statement will not run, which is why your index += 1 did not work. Return stops the function from running.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM