Idiom for default values when unpacking a tuple

P

Paul McGuire

I'm trying to manage some configuration data in a list of tuples, and I
unpack the values with something like this:

configList = [
("A",1,2,3),
("F",1,3,4),
("X",2,3,4),
("T",1,5,4),
("W",6,3,4),
("L",1,3,8),
]
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),

and I would like to avoid having to put 0's or None's in all of the others.
Is there a clean Python idiom for unpacking a tuple so that any unassigned
target values get a default, or None, as in:

tup = (1,2)
a,b,c = tup

gives a = 1, b = 2, and c = None.

I've tried creating a padUnpack class, but things aren't quite clicking...

TIA,
-- Paul
 
D

Diez B. Roggisch

You can always have a try/exept clause around unpacking. That you could
fator out into a function that always returns the right sized tuples. Like
this:

def unpack(t):
try:
a,b,c = t
d = None
except ValueError:
a,b,c,d = t
return a,b,c,d
 
J

Jeff Epler

A function to pad a tuple to a given length is not hard to write.
[l] * i is empty if i <= 0, otherwise it has i repetitions of l.

def pad(t,l):
return t + (None,) * (l - len(t))

tup = (1,2)
a, b, c = pad(tup, 3)
print a, b, c

Jeff

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (GNU/Linux)

iD8DBQFBmjMiJd01MZaTXX0RAlWuAJ9NYRLC8x8rkvZITiSBFbAs4mfeZQCeLWbV
28XJV/WFluHxo6P1mfWkE5w=
=TW1+
-----END PGP SIGNATURE-----
 
P

Paul McGuire

So is there any easy way for the pad function to figure out for itself that
the target length is 3, without my having to tell it so?

-- Paul
 
S

Scott David Daniels

Paul said:
So is there any easy way for the pad function to figure out for itself that
the target length is 3, without my having to tell it so?
Nope.
If there were, what would you propose the function "pad" below use as a
desired length in the statement:

a,b,c = pad(something)[1:4]

--Scott David Daniels
(e-mail address removed)
 
C

Carlos Ribeiro

I'm trying to manage some configuration data in a list of tuples, and I
unpack the values with something like this:

configList = [
("A",1,2,3),
("F",1,3,4),
("X",2,3,4),
("T",1,5,4),
("W",6,3,4),
("L",1,3,8),
]
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),

and I would like to avoid having to put 0's or None's in all of the others.
Is there a clean Python idiom for unpacking a tuple so that any unassigned
target values get a default, or None, as in:

tup = (1,2)
a,b,c = tup

gives a = 1, b = 2, and c = None.

I've tried creating a padUnpack class, but things aren't quite clicking...

TIA,
-- Paul

How about having a iterator function that is guaranteed to always
return a fixed number of elements, regardless of the size of the
sequence? I've checked it, and it does not exist in itertools.
Something like this (simple-minded, just a proof of concept, and
highly optimizable in at least a hundred different ways :):

def iterfixed(seq, times, defaultitem=None):
for i in range(times):
if i < len(seq):
yield seq
else:
yield defaultitem

To unpack a tuple using it, it's simply a matter to use it like this:
(1, 2, 3, 4, None, None)

In fact, if you *are* doing tuple unpacking, *you don't have to build
the tuple*. You can simply do it like this:
(1, 2, 3, 4, None, None)

The only catch is that, if you have only one parameter, then all you
will get is the generator itself. But that's a corner case, and not
the intended use anyway.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: (e-mail address removed)
mail: (e-mail address removed)
 
S

Steven Bethard

Carlos said:
How about having a iterator function that is guaranteed to always
return a fixed number of elements, regardless of the size of the
sequence? I've checked it, and it does not exist in itertools.
Something like this (simple-minded, just a proof of concept, and
highly optimizable in at least a hundred different ways :):

def iterfixed(seq, times, defaultitem=None):
for i in range(times):
if i < len(seq):
yield seq
else:
yield defaultitem


Well, it doesn't quite exist in itertools, but it's there with just a
simple composition:
.... return it.islice(it.chain(iter(seq), it.repeat(defaultitem)), times)
....(1, 2, 3, 4, None, None)
The only catch is that, if you have only one parameter, then all you
will get is the generator itself. But that's a corner case, and not
the intended use anyway.

Not exactly sure what you mean here. If you only have one item in your
unpack tuple, I believe things still work, e.g.:
1

But I'm probably just misunderstanding your statement...

Steve
 
C

Carlos Ribeiro

Well, it doesn't quite exist in itertools, but it's there with just a
simple composition:

... return it.islice(it.chain(iter(seq), it.repeat(defaultitem)), times)
...

After I posted the previous recipe I polished it up a little bit more
and renamed it as "iunpack". It now returns the remaining part of the
tuple as the last item. As it is, it's a good candidate for itertools
-- it's way more convenient than the composition option, and judging
by how many times the issue was brought up here, it's a relatively
common problem.
(1, 2, 3, 4, None, None)


Not exactly sure what you mean here. If you only have one item in your
unpack tuple, I believe things still work, e.g.:

1

But I'm probably just misunderstanding your statement...

No -- it's that you remembered to include the comma. My example was to
assign it it one item only, which really isn't tuple unpacking; but
this is a easy mistake to do in this case. Anyway, it should work as
intended.

BTW, I never saw it mentioned before that iterators can be used at the
right side of an assignment with the tuple meaning. Nice side effect,
I think.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: (e-mail address removed)
mail: (e-mail address removed)
 
M

Mark Wooding

Paul McGuire said:
Is there a clean Python idiom for unpacking a tuple so that any
unassigned target values get a default, or None

If i is a tuple you want unpacked, then something like

(lambda a, b, c, d = None: (a, b, c, d))(*i)

is the expanded version with defaults substituted.

-- [mdw]
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top