Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Python Cookbook 2Nd Edition Jun 1002005 [Electronic resources] - نسخه متنی

David Ascher, Alex Martelli, Anna Ravenscroft

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید







Recipe 19.4. Unpacking a Few Items in a Multiple Assignment


Credit: Brett Cannon, Oren Tirosh, Alex Martelli


Problem


Python's multiple
unpacking assignment is very handy when you are unpacking all the
items from a sequence and binding each to a name. However, you often
need to unpack (and bind to names) only some items from the
"front" of a sequence, and bind
another name to "the rest" of the
sequence (the part you didn't unpack).


Solution


A generator provides an elegant solution to this problem:

def peel(iterable, arg_cnt=1):
"" Yield each of the first arg_cnt items of the iterable, then
finally an iterator for the rest of the iterable. ""
iterator = iter(iterable)
for num in xrange(arg_cnt):
yield iterator.next( )
yield iterator
if _ _name_ _ == '_ _main_ _':
t5 = range(1, 6)
a, b, c = peel(t5, 2)
print a, b, list(c)
# emits: 1 2 [3, 4, 5]


Discussion


Python supports the handy idea of multiple unpacking assignment. Say
that t5 is any sequence of five items.
Then, you can code:

a, b, c, d, e = t5

to bind a name to each item of t5.

However, you often do not know (nor care) exactly how many items a
certain sequence t holds: you want to bind
(say) two names, one to each of the first two items, and a third name
to "the rest" of
t (this requirement does imply that t must
hold at least two items). If you know that
t is a
"proper" sequence, with support for
slicing, not just an arbitrary iterable, you can code:

a, b = t[:2]
c = t[2:]

but this is nowhere as elegant or handy as the multiple unpacking
assignment. Moreover, if you are not certain about the nature of
t (i.e., if t
can be any iterable, not necessarily supporting slice syntax), the
task becomes more cumbersome:

c = iter(t5)
a = c.next( )
b = c.next( )

Given these issues, the Python Development mailing list[1] once discussed a new
syntax for generalized multiple unpacking assignment, such that:

[1] The Python Development mailing list is the list on which all
discussion regarding the development of Python itself is held; see
http://mail.python.org/pipermail/python-dev/2002-November/030380l
for this specific subject.


a, b, *c = t

would perform exactly this taskbind names
a and b to the
first two items of t and name
c to "the
rest".

I didn't like the idea of making the Python language
bigger by adding this extra functionality to assignment statements,
so I came up with this recipe's generator. This
generator provides this functionality fully and without any need to
add any new syntax to Python.

Just one caveat: you must make sure that you pass the
arg_cnt argument properly. If you pass a wrong value
for arg_cnt, or if the sequence you pass to
peel is shorter than arg_cnt, you
get an exception at runtime. But then, you also get a Python
exception at runtime if you try to perform a multiple assignment and
the number of names you have on the left of the =
sign is not identical to the number of items of the sequence you have
on the right. Therefore, this recipe isn't any
different from normal, multiple unpacking assignment in this respect.
If you think it is important to relax some parts of this requirement,
see Recipe 19.5.


See Also


Language Reference and Python in a
Nutshell
about multiple unpacking assignments; Recipe 19.5.


/ 394