def mrange2(start, end, length, type_ = None):
if hasattr(start, '__iter__'):
return zip(*[mrange(a, b, length, type_)for a, b in zip(start, end)])
ret, step = [], float(end_ - start_) / (length - 1)
if type(start) is int and type(end) is int and type_ is None:
type_ = int
while start_ != end_:
if type_ is int:
ret.append(int(round(start_)))
else:
ret.append(float(start_))
start_ += step
ret.append(end_)
return ret
Sinon, voici une solution pour accorder les résultats avec les valeurs réels : ajouter un argument ndigit.
mrange(start, stop, length[, type_[, ndigit]])
Exemple :
def mrange(start, stop, length, type_=None, ndigit=None):
"mrange(start, stop, length[, type_[, ndigit]]) -> generator object"
if hasattr(start, "__iter__"):
# tuple
return zip(*( mrange(a, b, length, type_, ndigit)
for a, b in zip(start, stop) ))
step = (stop - start) / (length - 1)
if type_ is int or (type_ is None and type(start) is int and type(stop) is int):
# int
return ( round(start + step * i) for i in range(length - 1) )
elif ndigit is not None:
# int if ndigit < 0 else float
return ( round(start + step * i, ndigit)
for i in range(length - 1) )
# float
return ( start + step * i for i in range(length - 1) )
Pour me rapprocher un peu plus du comportement du range standard, j'ai exclu stop du resultat (mais c'est pas compliqué à rajouter ).
def mrange2(start, end, length, type_ = None):
if hasattr(start, '__iter__'):
return zip(*[mrange(a, b, length, type_)for a, b in zip(start, end)])
ret, step = [], float(end_ - start_) / (length - 1)
if type(start) is int and type(end) is int and type_ is None:
type_ = int
while start_ != end_:
if type_ is int:
ret.append(int(round(start_)))
else:
ret.append(float(start_))
start_ += step
ret.append(end_)
return ret
chez moi ça boucle à l'infini avec mrange(0,201,400)
chez moi ça boucle à l'infini avec mrange(0,201,400)
Bah, remarque avec un test d'égalité sur des flottants je cherchais les problèmes aussi.
Je regarde ça.
En même temps, hormis ma première solution, je ne vois pas trop comment faire.
edit:
aie: le problème est plus profond, mon second code c'est n'importe quoi.
Je corrige vite, très vite...
edit:
Je pense que ce sera mieux.
def mrange3(start, end, length, type_ = None):
if hasattr(start, '__iter__'):
return zip(*[mrange3(a, b, length, type_)for a, b in zip(start, end)])
ret, step = [], float(end - start) / (length - 1)
if type(start) is int and type(end) is int and type_ is None:
type_ = int
while length > 0:
if type_ is int:
ret.append(int(round(start)))
else:
ret.append(float(start))
start += step
length -= 1
return ret
La seule explication que je vois pour le code précédent, c'est que j'ai testé en appelant mrange et pas mrange2, je ne vois pas comment c'est possible sinon.
Ah, d'ac ! Je pensais que c'était autre chose parce que dans les codes proposés il y a ifhasattr(start,'__iter__'): et j'étais pas sûr. Visiblement il y a un autre moyen.
Je vais tenter de me casser les dents dessus.
Merci.
Pour voir si le type est un tuple, c'est la même chose.
Sauf qu'ici il est plus intéressant de savoir si le type en entré est itérable. Et pour savoir ça, on vérifie que l'objet contient bien une méthode (aussi appelé attribut) __iter__ avec la fonction hasattr.
Ah, c'est bon je comprends mieux d'un coup. Merci.
Petite question : un tuple est forcément itérable ? Il va falloir que je me renseigne sur l'oo aussi.
Oui. Tout les objets indexables sont itérables. Du moins je crois...
En effet tous les objets indexables sont itérables, mais la réciproque n'est pas vraie.
Par exemple, les générateurs sont itérables mais pas indexables :
>>> def foo():
for n in range(10):
yield n
>>> foo()
<generator object foo at 0xa52cd24>
>>> foo()[1]
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
foo()[1]
TypeError: 'generator' object is not subscriptable
>>> hasattr(foo(), '__iter__')
True
Pour la définition exacte des itérables en Python, le plus simple est de se référer à la doc:
Citation : Doc Python v2.7
iterable
A container object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict and file and objects of any classes you define with an __iter__() or __getitem__() method. Iterables can be used in a for loop and in many other places where a sequence is needed (zip(), map(), ...). When an iterable object is passed as an argument to the built-in function iter(), it returns an iterator for the object. This iterator is good for one pass over the set of values. When using iterables, it is usually not necessary to call iter() or deal with iterator objects yourself. The for statement does that automatically for you, creating a temporary unnamed variable to hold the iterator for the duration of the loop. See also iterator, sequence, and generator.
Pour résumer c'est un objet qui peut en contenir d'autres et renvoyer les objets qu'il contient un par un, c'est tout. Étant donné qu'un tuple respecte cette définition, un tuple est donc forcément itérable.
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Python c'est bon, mangez-en.