
July 18th, 2005, 06:40 PM
| | | Idiom for default values when unpacking a tuple
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 |

July 18th, 2005, 06:40 PM
| | | Re: Idiom for default values when unpacking a tuple
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
--
Regards,
Diez B. Roggisch | 
July 18th, 2005, 06:40 PM
| | | Re: Idiom for default values when unpacking a tuple
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)
iD8DBQFBmjMiJd01MZaTXX0RAlWuAJ9NYRLC8x8rkvZITiSBFb As4mfeZQCeLWbV
28XJV/WFluHxo6P1mfWkE5w=
=TW1+
-----END PGP SIGNATURE----- | 
July 18th, 2005, 06:40 PM
| | | Re: Idiom for default values when unpacking a tuple
"Jeff Epler" <jepler@unpythonic.net> wrote in message
news:mailman.6434.1100624680.5135.python-list@python.org...
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 | 
July 18th, 2005, 06:45 PM
| | | Re: Idiom for default values when unpacking a tuple
Paul McGuire wrote:[color=blue]
> 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?[/color]
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 Scott.Daniels@Acm.Org | 
July 18th, 2005, 06:46 PM
| | | Re: Idiom for default values when unpacking a tuple
On Tue, 16 Nov 2004 16:42:57 GMT, Paul McGuire
<ptmcg@austin.rr._bogus_.com> wrote:[color=blue]
> 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[/color]
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[i]
else:
yield defaultitem
To unpack a tuple using it, it's simply a matter to use it like this:
[color=blue][color=green][color=darkred]
>>> tuple(iterfixed((1,2,3,4), 3))[/color][/color][/color]
(1, 2, 3)[color=blue][color=green][color=darkred]
>>> tuple(iterfixed((1,2,3,4), 6))[/color][/color][/color]
(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:
[color=blue][color=green][color=darkred]
>>> a,b,c = iterfixed((1,2,3,4), 3)
>>> a,b,c[/color][/color][/color]
(1, 2, 3)[color=blue][color=green][color=darkred]
>>> a,b,c,d,e,f = iterfixed((1,2,3,4), 6)
>>> a,b,c,d,e,f[/color][/color][/color]
(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: carribeiro@gmail.com
mail: carribeiro@yahoo.com | 
July 18th, 2005, 06:46 PM
| | | Re: Idiom for default values when unpacking a tuple
Carlos Ribeiro wrote:[color=blue]
> 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[i]
> else:
> yield defaultitem[/color]
Well, it doesn't quite exist in itertools, but it's there with just a
simple composition:
[color=blue][color=green][color=darkred]
>>> def iterfixed(seq, times, defaultitem=None):[/color][/color][/color]
.... return it.islice(it.chain(iter(seq), it.repeat(defaultitem)), times)
....[color=blue][color=green][color=darkred]
>>> tuple(iterfixed((1,2,3,4), 3))[/color][/color][/color]
(1, 2, 3)[color=blue][color=green][color=darkred]
>>> tuple(iterfixed((1,2,3,4), 6))[/color][/color][/color]
(1, 2, 3, 4, None, None)[color=blue][color=green][color=darkred]
>>> a,b,c = iterfixed((1,2,3,4), 3)
>>> a,b,c[/color][/color][/color]
(1, 2, 3)[color=blue][color=green][color=darkred]
>>> a,b,c,d,e,f = iterfixed((1,2,3,4), 6)
>>> a,b,c,d,e,f[/color][/color][/color]
(1, 2, 3, 4, None, None)
[color=blue]
> 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.[/color]
Not exactly sure what you mean here. If you only have one item in your
unpack tuple, I believe things still work, e.g.:
[color=blue][color=green][color=darkred]
>>> a, = iterfixed((1,2,3,4), 1)
>>> a[/color][/color][/color]
1
But I'm probably just misunderstanding your statement...
Steve | 
July 18th, 2005, 06:47 PM
| | | Re: Idiom for default values when unpacking a tuple
On Thu, 18 Nov 2004 03:34:42 GMT, Steven Bethard
<steven.bethard@gmail.com> wrote:[color=blue]
> Well, it doesn't quite exist in itertools, but it's there with just a
> simple composition:
>[color=green][color=darkred]
> >>> def iterfixed(seq, times, defaultitem=None):[/color][/color]
> ... return it.islice(it.chain(iter(seq), it.repeat(defaultitem)), times)
> ...[/color]
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.
[color=blue][color=green][color=darkred]
> >>> tuple(iterfixed((1,2,3,4), 3))[/color][/color]
> (1, 2, 3)[color=green][color=darkred]
> >>> tuple(iterfixed((1,2,3,4), 6))[/color][/color]
> (1, 2, 3, 4, None, None)[color=green][color=darkred]
> >>> a,b,c = iterfixed((1,2,3,4), 3)
> >>> a,b,c[/color][/color]
> (1, 2, 3)[color=green][color=darkred]
> >>> a,b,c,d,e,f = iterfixed((1,2,3,4), 6)
> >>> a,b,c,d,e,f[/color][/color]
> (1, 2, 3, 4, None, None)
>[color=green]
> > 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.[/color]
>
> Not exactly sure what you mean here. If you only have one item in your
> unpack tuple, I believe things still work, e.g.:
>[color=green][color=darkred]
> >>> a, = iterfixed((1,2,3,4), 1)
> >>> a[/color][/color]
> 1
>
> But I'm probably just misunderstanding your statement...[/color]
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: carribeiro@gmail.com
mail: carribeiro@yahoo.com | 
July 18th, 2005, 07:03 PM
| | | Re: Idiom for default values when unpacking a tuple
Paul McGuire <ptmcg@austin.rr._bogus_.com> wrote:
[color=blue]
> Is there a clean Python idiom for unpacking a tuple so that any
> unassigned target values get a default, or None[/color]
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] | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 205,414 network members.
|