473,607 Members | 2,659 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Tuple assignment and generators?

Just as a pedantic exercise to try and understand Python a
bit better, I decided to try to make a generator or class
that would allow me to unpack an arbitrary number of
calculatible values. In this case, just zeros (though I
just to prove whatever ends up working, having a counting
generator would be nice). The target syntax would be
something like
a,b,c = zeros()
q,r,s,t,u,v = zeros()
where "zeros()" returns an appropriately sized tuple/list of
zeros.

I've tried a bit of googling, but all my attempts have just
ended up pointing to pages that blithly describe tuple
assignment, not the details of what methods are called on an
object in the process.

My first thought was to get it to use a generator:

def zeros():
while 1: yield 0

However, I get back a "ValueError : too many values to
unpack" result.

As a second attempt, I tried a couple of attempts at classes
(I started with the following example class, only derived
from "object" rather than "list", but it didn't have any
better luck):
class zeros(list): .... def __getitem__(sel f,i):
.... return 0
.... z = zeros()
a,b,c = z

Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: need more than 0 values to unpack
It looks like I need to have a pre-defined length, but I'm
having trouble figuring out what sorts of things need to be
overridden. It seems like I sorta need a

def __len__(self):
return INFINITY

so it doesn't choke on it. However, how to dupe the
interpreter into really believing that the object has the
desired elements is escaping me. Alternatively if there was
a "doYouHaveThisM anyElements" pseudo-function that was
called, I could lie and always return true.

Any hints on what I'm missing?

Thanks,

-tkc


May 4 '06 #1
43 3351
Tim Chase wrote:
Just as a pedantic exercise to try and understand Python a
bit better, I decided to try to make a generator or class
that would allow me to unpack an arbitrary number of
calculatible values. In this case, just zeros (though I
just to prove whatever ends up working, having a counting
generator would be nice). The target syntax would be
something like


<snip/>

By using this:

http://aspn.activestate.com/ASPN/Coo.../Recipe/284742
I came up with a small decorator doing that:

import inspect, dis

def expecting():
"""Return how many values the caller is expecting"""
f = inspect.current frame()
f = f.f_back.f_back
c = f.f_code
i = f.f_lasti
bytecode = c.co_code
instruction = ord(bytecode[i+3])
if instruction == dis.opmap['UNPACK_SEQUENC E']:
howmany = ord(bytecode[i+4])
return howmany
elif instruction == dis.opmap['POP_TOP']:
return 0
return 1

def variably_unpack (f):
def d(*args, **kwargs):
r = f(*args, **kwargs)
exp = expecting()
if exp < 2:
return exp
return (r.next() for i in xrange(exp))
return d

@variably_unpac k
def test():
def gen():
i = 0
while True:
yield i
i += 1
return gen()

a, b, c = test()

print a,b,c

a, b, c, d = test()

print a,b,c, d

Diez
May 4 '06 #2

Tim Chase wrote:
Just as a pedantic exercise to try and understand Python a bit better, I
decided to try to make a generator or class that would allow me to
unpack an arbitrary number of calculatible values. In this case, just
zeros (though I just to prove whatever ends up working, having a
counting generator would be nice). The target syntax would be something
like
a,b,c = zeros()
q,r,s,t,u,v = zeros()
where "zeros()" returns an appropriately sized tuple/list of zeros.

I've tried a bit of googling, but all my attempts have just ended up
pointing to pages that blithly describe tuple assignment, not the
details of what methods are called on an object in the process.

My first thought was to get it to use a generator:

def zeros():
while 1: yield 0

However, I get back a "ValueError : too many values to unpack" result.

As a second attempt, I tried a couple of attempts at classes (I started
with the following example class, only derived from "object" rather than
"list", but it didn't have any better luck):
class zeros(list): ... def __getitem__(sel f,i):
... return 0
... z = zeros()
a,b,c = z

Traceback (most recent call last):
File "<stdin>", line 1, in ?
ValueError: need more than 0 values to unpack
It looks like I need to have a pre-defined length, but I'm having
trouble figuring out what sorts of things need to be overridden. It
seems like I sorta need a

def __len__(self):
return INFINITY

so it doesn't choke on it. However, how to dupe the interpreter into
really believing that the object has the desired elements is escaping
me. Alternatively if there was a "doYouHaveThisM anyElements"
pseudo-function that was called, I could lie and always return true.

Any hints on what I'm missing?

Thanks,

-tkc

While I have never needed anything like this in my 5 years of Python
programming, here is a way:

a,b,c = 3*[0]
q,r,s,t,u,v = 6*[0]

of if you like:

def zeros(num):
return num*[0]

a,b,c = zeros(3)
q,r,s,t,u,v = zeros(6)

I think the reason I don't every use anything like this is that
you don't need to initialize variables in Python to zero and I would
probably use a list instead of individual variables like q,r,s,t,u,v.

-Larry Bates

May 4 '06 #3
Ant
I don't think he was explicitly wanting to initialize things to zero,
but rather unpack an arbitrary sequence into a tuple (could perhaps be
the fibonnacci sequence for example).

How about:
def zeros(count): .... for i in range(count):
.... yield 0
.... a,b,c = zeros(3)
a 0 b 0 c

0

May 4 '06 #4
In article <0K************ *************** ***@comcast.com >,
Larry Bates <la*********@we bsafe.com> wrote:
While I have never needed anything like this in my 5 years of Python
programming, here is a way:

a,b,c = 3*[0]
q,r,s,t,u,v = 6*[0]


This is (IMO) fairly idiomatic:

a = b = c = 0
q = r = s = t = u = v = 0

Just
May 4 '06 #5
Just wrote:
In article <0K************ *************** ***@comcast.com >,
Larry Bates <la*********@we bsafe.com> wrote:
While I have never needed anything like this in my 5 years of Python
programming, here is a way:

a,b,c = 3*[0]
q,r,s,t,u,v = 6*[0]


This is (IMO) fairly idiomatic:

a = b = c = 0
q = r = s = t = u = v = 0

Just


You must be careful with this as they all point to
exactly the same object. Example:
q = r = s = t = u = v = 0
id(q) 3301924 id(r) 3301924 id(s) 3301924
Notice that all of them point to exactly the same object,
not 6 copies of zero which is "probably" what the poster
was thinking.

Most of the time when I see this, it is because people are
thinking of variables having values which is mostly a
carry-over from old Fortran/Cobol/Basic programming ideas.
In python variables are pointers to objects. Objects could
be values, but they are not placeholders where you store
stuff.

I read on this list (quite frequently) that people
think they are getting 6 separate variables each with
a zero stored in them. They are not. They are getting
six pointers that all point to an integer zero (IMHO it
would be a rather odd application for a programmer
to want this). Here is where multiple assignments
causes problems for beginners:
a=[]
b=c=a
a.append(6)
b

[6]

What?? 'b' should contain an empty list, right? Nope.
a, b, and c all point to the SAME list just like the
poster's q, r, s, t, u, v all point to the SAME zero.

What they meant to write was:

c=a[:] # Shallow copy of list
b=a[:]

My rule, don't do it unless you know exactly why you
want to do it. It will trip you up at some point and
be VERY hard to find.

-Larry Bates
May 4 '06 #6
> I don't think he was explicitly wanting to initialize
things to zero, but rather unpack an arbitrary sequence
into a tuple (could perhaps be the fibonnacci sequence
for example).
Ant is correct here...Fibonnac i, digits of pi, the constant
42, an incrementing counter, a series of squares, whatever.
That was my original intent in the matter. Zeros just
happened to be a nice sort of place to start my exercise.
How about:

def zeros(count):
... for i in range(count):
... yield 0


One of the things I was trying to avoid was having to know
(and maintain) the count of items initialized. In the
theoretical world of my example, one could do something like

def counter():
counter = 0
while 1:
yield counter
counter += 1

and then initialize several variables, such as
a,b,c,d,e,f,g = counter()
a,b,c,d,e,f,g

(0,1,2,3,4,5,6)

It's similar to C's auto-numbering of enum values...If I
want to add another entry to a C enum, I just put it there,
and let the language take care of matters. With most of the
provided solutions, I also have to increment the count each
time I add an item to the list.

Diez provided an elegant solution with a decorator
(employing an incredibly ugly sort of hack involving
sniffing the opcode stack behind the scenes) that does what
I was looking for.

I was hoping that there was just some __foo__ property I was
missing that would have been called in the process of tuple
unpacking that would allow for a more elegant solution such
as a generator (or generator method on some object) rather
than stooping to disassembling opcodes. :)

Ah well.

-tkc


May 4 '06 #7

Larry Bates wrote:
Just wrote:
In article <0K************ *************** ***@comcast.com >,
Larry Bates <la*********@we bsafe.com> wrote:
While I have never needed anything like this in my 5 years of Python
programming, here is a way:

a,b,c = 3*[0]
q,r,s,t,u,v = 6*[0]
This is (IMO) fairly idiomatic:

a = b = c = 0
q = r = s = t = u = v = 0

Just


You must be careful with this as they all point to
exactly the same object. Example:
q = r = s = t = u = v = 0
id(q) 3301924 id(r) 3301924 id(s) 3301924
Notice that all of them point to exactly the same object,
not 6 copies of zero which is "probably" what the poster
was thinking.


Numbers are immutable. They're never copied. Zero, in particular, is
the same variable all throughout a Python interpreter.
Most of the time when I see this, it is because people are
thinking of variables having values which is mostly a
carry-over from old Fortran/Cobol/Basic programming ideas.
Most of the time when I see it, it's written by someone who's used
Python for quite some time. It's a standard Python idiom. You'll find
it all over the standard library. It's not a carry-over from
Fortran/Cobol/Basic at all.
In python variables are pointers to objects. Objects could
be values, but they are not placeholders where you store
stuff.
And all immutable objects are indistinguishab le from values. Immutable
objects include ints, longs, strings, unicode objects, tuples,
frozensets, and perhaps some others that I'm forgetting.
I read on this list (quite frequently) that people
think they are getting 6 separate variables each with
a zero stored in them.
That's because they are. They're getting 6 different pointers
(bindings) to zero. If you change one, the others remain pointed at
(bound to) zero.
They are not. They are getting
six pointers that all point to an integer zero
Six *different* pointers. Six *different* bindings.
(IMHO it
would be a rather odd application for a programmer
to want this).
No, it wouldn't be. It's exactly how a person works with immutable
(value) objects.
Here is where multiple assignments
causes problems for beginners:
a=[]
b=c=a
a.append(6)
b
[6]


Yes, that does sometimes trouble beginners to programming. But so do
regular expressions. Programmers ought not to restrict themselves by
what beginners will have no difficulty learning.
What?? 'b' should contain an empty list, right? Nope.
a, b, and c all point to the SAME list just like the
poster's q, r, s, t, u, v all point to the SAME zero.
There is only one zero in Python! It can never change!
What they meant to write was:

c=a[:] # Shallow copy of list
b=a[:]

My rule, don't do it unless you know exactly why you
want to do it. It will trip you up at some point and
be VERY hard to find.


Your rule should only be followed by people who obstinately refuse
either to understand the way variable bindings work in Python, or by
people who refuse to know or care whether a given kind of object is
immutable. And that group of people doesn't seem to include any of the
good Python programmers I know.

Jeremy

May 5 '06 #8
> Zero, in particular, is the same variable all throughout a Python interpreter.

For the sake of accuracy let me note that I ought to have said, "is the
same *value* all throughout a Python interpreter."

Jeremy

May 5 '06 #9
je******@gmail. com writes:
There is only one zero in Python! It can never change!


+0.5 QOTW

--
\ "Madness is rare in individuals, but in groups, parties, |
`\ nations and ages it is the rule." -- Friedrich Nietzsche |
_o__) |
Ben Finney

May 5 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
4947
by: sosman | last post by:
I take it python doesn't support defaults when assigning to a tuple, eg: for line in file: (parameter, value, units = 'kg') = line.split() along the lines of default parameter assignment in function calls.
50
3671
by: Will McGugan | last post by:
Hi, Why is that a tuple doesnt have the methods 'count' and 'index'? It seems they could be present on a immutable object. I realise its easy enough to convert the tuple to a list and do this, I'm just curious why it is neccesary.. Thanks,
8
3622
by: Paul McGuire | last post by:
I'm trying to manage some configuration data in a list of tuples, and I unpack the values with something like this: configList = for data in configList: name,a,b,c = data ... do something with a,b, and c Now I would like to add a special fourth config value to "T": ("T",1,5,4,0.005),
5
1679
by: Chris | last post by:
Hi Consider the following tuples: >>> t = (,) >>> u = (1,2) >>> v = ('1','2') >>> t (, ) >>> u (1, 2)
12
1596
by: Kay Schluehr | last post by:
Hi all, thanks for Your attention ! I think my proposal was more in mind of Rons modified exec than Pythons lambda. When George proposed his unpacking behavoir for list-comps as a pack of suggar:
4
1798
by: Peter Notebaert | last post by:
I am new to Python and have to create an import library in C that uses matrices. These matrices can be one-dimensional (vectors) or two-dimensional. If I look in the ActivePython 2.4 documentation at data structures, then I see at least 2 posibilities to represent them: Lists and Tuples. The documention doesn't give me much information on what the best choice is for the data type to provide/return these matrices.
2
3723
by: Ministeyr | last post by:
Hello, os.walk doc: http://www.python.org/doc/2.4/lib/os-file-dir.html#l2h-1625 When walking top to bottom, it allows you to choose the directories you want to visit dynamically by changing the second parameter of the tuple (a list of directories). However, since it is a tuple, you cannot use "filter" on it, since it would mean reassigning it: for dir_tuple in os.walk('/home'):
11
2660
by: montyphyton | last post by:
Recently, I got into a debate on programming.reddit.com about what should happen in the following case: Currently, Python raises an error *and* changes the first element of the tuple. Now, this seems like something one would want to change - why raise an error *and* execute the thing it was complaining about? The discussion seems to have no end, and that is why I'm posting here. I would like to know what is the opinion of the people...
0
1784
by: Hatem Nassrat | last post by:
on Wed Jun 13 10:17:24 CEST 2007, Diez B. Roggisch deets at nospam.web.de wrote: Well I have looked into this and it seems that using the list comprehension is faster, which is reasonable since generators require iteration and stop iteration and what not.
0
8050
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
7987
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8472
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8464
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8324
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6805
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6000
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
3954
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4015
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.