Quantcast

[Tutor] list of dicts <-> dict of lists?

classic Classic list List threaded Threaded
17 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[Tutor] list of dicts <-> dict of lists?

David Perlman-2
Using the csv.DictReader and csv.DictWriter lets you read and write  
lists of dictionaries from files containing tabular data.  I have a  
system that naturally generates tabular data in the form of a  
dictionary of lists: the dictionary key is the name of the column, and  
then the value is a list which contains the data for that column.  
Sort of like a spreadsheet.  I would like to use csv.DictWriter to  
write out this data but that requires a list of dicts.

I can convert the dict of lists to a list of dicts, and thus make it  
compatible with csv.DictWriter, with the following ugly comprehensions:

 >>> y
{'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
 >>> [dict([(i,y[i][j]) for i in y.keys()]) for j in  
range(len(y[y.keys()[0]]))]
[{'a': 1, 'c': 7, 'b': 4}, {'a': 2, 'c': 8, 'b': 5}, {'a': 3, 'c': 9,  
'b': 6}]

...but I'm wondering if anyone knows of a more elegant way, perhaps  
something built-in suited for this purpose...

I am aware that any solution will only work if the lists in the dict  
are all the same length.  :)

Thanks!


--
-dave----------------------------------------------------------------
"Pseudo-colored pictures of a person's brain lighting up are
undoubtedly more persuasive than a pattern of squiggles produced by a
polygraph.  That could be a big problem if the goal is to get to the
truth."  -Dr. Steven Hyman, Harvard



_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Matthew Wood-6
#!/usr/bin/env python


Here's my best attempt.  I'm not sure if it's "simpler" than yours,
but for me it seems a bit cleaner.  Then again, I LOVE the zip
operator, and the '*' operator too.  :-)  Whenever I see a "transpose
this" type problem, I think zip.


y = {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}

print y

old = [dict([(i, y[i][j]) for i in y.keys()])
                          for j in range(len(y[y.keys()[0]]))]
print old


keys, values = zip(* y.items())
new = [dict([(i, j) for i, j in zip(keys, column)])
                    for column in zip(* values)]

print new

print new == old

I BELIEVE there's some new cool features in 2.6 or maybe 3.0 where
non-simultaneous access to my_dict.keys() and my_dict.values() will
keep them "paired up", but I don't know the details.  If you skipped
the upper line (setting keys and values) you'd be accessing y.keys() 3
times (in this example).  I'm not sure if you're guaranteed to have
the order remain the same for all three accesses.  If that's the case,
I'd change the code to be:

# This line isn't necessary #keys, values = zip(* y.items())
new = [dict([(i, j) for i, j in zip(y.keys(), column)])
                    for column in zip(* y.values())]

or even

# This line isn't necessary #keys, values = zip(* y.items())
new = [dict([(i, j) for i, j in zip(y, column)])
                    for column in zip(* y.values())]


But since I'm a coward, and I'd like my code to run on older versions
of python too, I'd leave the initial step.
--

I enjoy haiku
but sometimes they don't make sense;
refrigerator?


On Thu, May 27, 2010 at 4:15 PM, David Perlman <[hidden email]> wrote:

>
> Using the csv.DictReader and csv.DictWriter lets you read and write lists of dictionaries from files containing tabular data.  I have a system that naturally generates tabular data in the form of a dictionary of lists: the dictionary key is the name of the column, and then the value is a list which contains the data for that column.  Sort of like a spreadsheet.  I would like to use csv.DictWriter to write out this data but that requires a list of dicts.
>
> I can convert the dict of lists to a list of dicts, and thus make it compatible with csv.DictWriter, with the following ugly comprehensions:
>
> >>> y
> {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
> >>> [dict([(i,y[i][j]) for i in y.keys()]) for j in range(len(y[y.keys()[0]]))]
> [{'a': 1, 'c': 7, 'b': 4}, {'a': 2, 'c': 8, 'b': 5}, {'a': 3, 'c': 9, 'b': 6}]
>
> ...but I'm wondering if anyone knows of a more elegant way, perhaps something built-in suited for this purpose...
>
> I am aware that any solution will only work if the lists in the dict are all the same length.  :)
>
> Thanks!
>
>
> --
> -dave----------------------------------------------------------------
> "Pseudo-colored pictures of a person's brain lighting up are
> undoubtedly more persuasive than a pattern of squiggles produced by a
> polygraph.  That could be a big problem if the goal is to get to the
> truth."  -Dr. Steven Hyman, Harvard
>
>
>
> _______________________________________________
> Tutor maillist  -  [hidden email]
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Mark Lawrence
I confess that I don't like top posting :)  Please see below.

On 28/05/2010 00:19, Matthew Wood wrote:

> #!/usr/bin/env python
>
>
> Here's my best attempt.  I'm not sure if it's "simpler" than yours,
> but for me it seems a bit cleaner.  Then again, I LOVE the zip
> operator, and the '*' operator too.  :-)  Whenever I see a "transpose
> this" type problem, I think zip.
>
>
> y = {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
>
> print y
>
> old = [dict([(i, y[i][j]) for i in y.keys()])
>                            for j in range(len(y[y.keys()[0]]))]
> print old
>
>
> keys, values = zip(* y.items())
> new = [dict([(i, j) for i, j in zip(keys, column)])
>                      for column in zip(* values)]
>
> print new
>
> print new == old
>
> I BELIEVE there's some new cool features in 2.6 or maybe 3.0 where
> non-simultaneous access to my_dict.keys() and my_dict.values() will
> keep them "paired up", but I don't know the details.  If you skipped
> the upper line (setting keys and values) you'd be accessing y.keys() 3
> times (in this example).  I'm not sure if you're guaranteed to have
> the order remain the same for all three accesses.  If that's the case,
> I'd change the code to be:
>
> # This line isn't necessary #keys, values = zip(* y.items())
> new = [dict([(i, j) for i, j in zip(y.keys(), column)])
>                      for column in zip(* y.values())]
>
> or even
>
> # This line isn't necessary #keys, values = zip(* y.items())
> new = [dict([(i, j) for i, j in zip(y, column)])
>                      for column in zip(* y.values())]
>
>
RTFM? :)  From the Python docs for 2.6.5
"items()
Return a copy of the dictionary’s list of (key, value) pairs.

CPython implementation detail: Keys and values are listed in an
arbitrary order which is non-random, varies across Python
implementations, and depends on the dictionary’s history of insertions
and deletions.

If items(), keys(), values(), iteritems(), iterkeys(), and itervalues()
are called with no intervening modifications to the dictionary, the
lists will directly correspond. This allows the creation of (value, key)
pairs using zip(): pairs = zip(d.values(), d.keys()). The same
relationship holds for the iterkeys() and itervalues() methods: pairs =
zip(d.itervalues(), d.iterkeys()) provides the same value for pairs.
Another way to create the same list is pairs = [(v, k) for (k, v) in
d.iteritems()]."

> But since I'm a coward, and I'd like my code to run on older versions
> of python too, I'd leave the initial step.
> --
>
> I enjoy haiku
> but sometimes they don't make sense;
> refrigerator?
>
>
> On Thu, May 27, 2010 at 4:15 PM, David Perlman<[hidden email]>  wrote:
>>
>> Using the csv.DictReader and csv.DictWriter lets you read and write lists of dictionaries from files containing tabular data.  I have a system that naturally generates tabular data in the form of a dictionary of lists: the dictionary key is the name of the column, and then the value is a list which contains the data for that column.  Sort of like a spreadsheet.  I would like to use csv.DictWriter to write out this data but that requires a list of dicts.
>>
>> I can convert the dict of lists to a list of dicts, and thus make it compatible with csv.DictWriter, with the following ugly comprehensions:
>>
>>>>> y
>> {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
>>>>> [dict([(i,y[i][j]) for i in y.keys()]) for j in range(len(y[y.keys()[0]]))]
>> [{'a': 1, 'c': 7, 'b': 4}, {'a': 2, 'c': 8, 'b': 5}, {'a': 3, 'c': 9, 'b': 6}]
>>
>> ...but I'm wondering if anyone knows of a more elegant way, perhaps something built-in suited for this purpose...
>>
>> I am aware that any solution will only work if the lists in the dict are all the same length.  :)
>>
>> Thanks!
>>
>>
>> --
>> -dave----------------------------------------------------------------
>> "Pseudo-colored pictures of a person's brain lighting up are
>> undoubtedly more persuasive than a pattern of squiggles produced by a
>> polygraph.  That could be a big problem if the goal is to get to the
>> truth."  -Dr. Steven Hyman, Harvard
>>
>>
>>
>> _______________________________________________
>> Tutor maillist  -  [hidden email]
>> To unsubscribe or change subscription options:
>> http://mail.python.org/mailman/listinfo/tutor
> _______________________________________________
> Tutor maillist  -  [hidden email]
> To unsubscribe or change subscription options:
> http://mail.python.org/mailman/listinfo/tutor
>


_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Matthew Wood-6
Well, that makes a lot of sense.  I probably should have looked it up.  :-)

That said, the version with an extra line will work on python < 2.6,
so I'd probably just leave it that way.


But thanks the docs pointer.  Always useful.


That said, if I KNEW that my software was only to be implemented in
3.0 or greater, I'd go with the new, cool, slick,
shows-I-read-the-docs way!
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Steven D'Aprano-8
In reply to this post by Matthew Wood-6
On Fri, 28 May 2010 09:19:20 am Matthew Wood wrote:

> I BELIEVE there's some new cool features in 2.6 or maybe 3.0 where
> non-simultaneous access to my_dict.keys() and my_dict.values() will
> keep them "paired up", but I don't know the details.

This is not a new feature, but a very old feature. It became a
guaranteed promise of the language in Python 2.0:

http://docs.python.org/release/2.0/lib/typesmapping.html

and worked at least back to Python 1.5:

[steve@sylar ~]$ python1.5
Python 1.5.2 (#1, Apr  1 2009, 22:55:54)  [GCC 4.1.2 20070925 (Red Hat
4.1.2-27)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> # mess with the dict a little bit
... d['a'] = -1
>>> d['f'] = -1
>>> del d['a']
>>> d['f'] = 6
>>> d['a'] = 1
>>> print d
{'f': 6, 'd': 4, 'e': 5, 'b': 2, 'c': 3, 'a': 1}
>>> d.keys()
['f', 'd', 'e', 'b', 'c', 'a']
>>> d.values()
[6, 4, 5, 2, 3, 1]


Since this is guaranteed, your comment:

> # This line isn't necessary #keys, values = zip(* y.items())
...
> But since I'm a coward, and I'd like my code to run on older versions
> of python too, I'd leave the initial step.

is unfortunately cargo-cult programming (programming without
understanding what you are doing). This sounds bad, and it is, but
we've all been there and done that, so don't take offence.

Firstly, it's not necessary, and secondly, even if it was necessary, it
won't work in older versions:

>>> keys, items = zip(*d.items())
  File "<stdin>", line 1
    keys, items = zip(*d.items())
                      ^
SyntaxError: invalid syntax


So drop it. You either trust Python, or you don't, and if you don't, you
can't trust it to do *anything*. (If d.keys() and d.values() are buggy,
how do you know that zip() or d.items() aren't buggy too?)

The exception to this is if you are handling non-dict mappings that
don't make promises about keeping d.keys() and d.values() aligned in
order. And that requires a comment to show why you're doing what
otherwise would seen to be unnecessary work:

# Support badly-behaved mappings like mymodule.stupid_dict.
keys, items = zip(*d.items())
...

rather than:

# Appease the Python gods so they give us cargo and not bugs.
keys, values = zip(d.items())
...


See the difference between cargo cult programming and defensive
programming?





--
Steven D'Aprano
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Steven D'Aprano-8
In reply to this post by Matthew Wood-6
On Fri, 28 May 2010 09:44:36 am Matthew Wood wrote:

> That said, the version with an extra line will work on python < 2.6,
> so I'd probably just leave it that way.

Why?

That's like saying:

"I could write y = x+2 in Python, but y = 1+x+1 will work too, so I'll
write that instead, just in case."

Yes, I suppose that there are buggy Python implementations where x+2
doesn't work correctly but 1+x+1 does, and there might be stupid data
types that are the same, but do you really need to support such
badly-behaved objects?



--
Steven D'Aprano
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Matthew Wood-6
Wow.  Something horrible happened here.

http://xkcd.com/386/


I THOUGHT the guaranteed same-ordering of dict.keys and dict.values started in python 2.6.  That was a simple mistake.

It turns out, that's not the case.  But in general, access to dicts and sets is unordered, so you can't/don't/shouldn't count on ordering.  The solution to take keys and values from dict.items() DOES guarantee their ordering, even if dict.keys and dict.values aren't.  

That's all I was trying to say.  It's unfortunate that I had the python version  the guaranteed same-ordering wrong.


I'm certainly not trying to say that you shouldn't trust language features.  That's not it at all.

But imagine if that guaranteed behavior started in 2.5 for example.  Then, if you want your code to work on 2.3, you'd definitely want to pull them out of the dict via dict.items().



I think your response was quite rude.  I mean really, cargo cult programming?  May John Frum forgive your unnecessary aggression.  I just tried to suggest a solution and I think it's crappy that you accused me of "programming without understanding what you are doing".

I recognize that you told me not to take offense; but, no offense, nobody cared when Carrie Prejean (Miss California) said that either.



So, I do apologize for the mistake I made, and hopefully we (both you AND I) can nip this mailing-list flame-war in the bud.



Anyway, I hope David (the original questioner) got a little help, or at least another token for confirmation that any list comprehension solution will be semi-ugly/semi-complex.  


--

I enjoy haiku
but sometimes they don't make sense;
refrigerator?



_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Peter Otten
In reply to this post by David Perlman-2
David Perlman wrote:

> Using the csv.DictReader and csv.DictWriter lets you read and write
> lists of dictionaries from files containing tabular data.  I have a
> system that naturally generates tabular data in the form of a
> dictionary of lists: the dictionary key is the name of the column, and
> then the value is a list which contains the data for that column.
> Sort of like a spreadsheet.  I would like to use csv.DictWriter to
> write out this data but that requires a list of dicts.
>
> I can convert the dict of lists to a list of dicts, and thus make it
> compatible with csv.DictWriter, with the following ugly comprehensions:
>
>  >>> y
> {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
>  >>> [dict([(i,y[i][j]) for i in y.keys()]) for j in
> range(len(y[y.keys()[0]]))]
> [{'a': 1, 'c': 7, 'b': 4}, {'a': 2, 'c': 8, 'b': 5}, {'a': 3, 'c': 9,
> 'b': 6}]
>
> ...but I'm wondering if anyone knows of a more elegant way, perhaps
> something built-in suited for this purpose...
>
> I am aware that any solution will only work if the lists in the dict
> are all the same length.  :)

I think it's simpler and therefore more appropriate to use a normal
csv.writer here:

>>> import csv
>>> import sys
>>> data = {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
>>> writer = csv.writer(sys.stdout)
>>> writer.writerow(data.keys())
a,c,b
>>> writer.writerows(zip(*data.values()))
1,7,4
2,8,5
3,9,6

Peter

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

spir ☣
In reply to this post by Matthew Wood-6
On Thu, 27 May 2010 20:00:46 -0600
Matthew Wood <[hidden email]> wrote:

> I THOUGHT the guaranteed same-ordering of dict.keys and dict.values started
> in python 2.6.  That was a simple mistake.
>
> It turns out, that's not the case.  But in general, access to dicts and sets
> is unordered, so you can't/don't/shouldn't count on ordering.  The solution
> to take keys and values from dict.items() DOES guarantee their ordering,
> even if dict.keys and dict.values aren't.

The word "order" is a bit over-used :-)
Python's guarantee is that the *output* orders of keys() & value() match each other. Say, they're consistent // sequences. This is a different feature from preserving *input* order of of keys, or of key:value pairs. (Which is not true is Python or Lua, for instance, but in recent Ruby versions, yes: http://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash/.)

Denis
________________________________

vit esse estrany ☣

spir.wikidot.com
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Sander Sweers
2010/5/28 spir ☣ <[hidden email]>:
> his is a different feature from preserving *input* order of of keys, or of key:value pairs.

In Python 2.7 and 3.1 [1] we now have the OrderedDict which does
preserve input order.

Greets
Sander

[1] http://www.python.org/dev/peps/pep-0372/
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

David Perlman-2
In reply to this post by Peter Otten
Aha, now this is the clever solution that I didn't find "outside the  
box".  :)

On May 28, 2010, at 2:33 AM, Peter Otten wrote:

> I think it's simpler and therefore more appropriate to use a normal
> csv.writer here:
>
>>>> import csv
>>>> import sys
>>>> data = {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
>>>> writer = csv.writer(sys.stdout)
>>>> writer.writerow(data.keys())
> a,c,b
>>>> writer.writerows(zip(*data.values()))
> 1,7,4
> 2,8,5
> 3,9,6
>
> Peter

--
-dave----------------------------------------------------------------
"Pseudo-colored pictures of a person's brain lighting up are
undoubtedly more persuasive than a pattern of squiggles produced by a
polygraph.  That could be a big problem if the goal is to get to the
truth."  -Dr. Steven Hyman, Harvard



_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

David Perlman-2
In reply to this post by Peter Otten
Oh, except one problem: the csv.DictWriter lets you tell it what order  
you want the columns output in.  With your version, they just show up  
in whatever order Python wants them.

On May 28, 2010, at 2:33 AM, Peter Otten wrote:

> I think it's simpler and therefore more appropriate to use a normal
> csv.writer here:
>
>>>> import csv
>>>> import sys
>>>> data = {'a': [1, 2, 3], 'c': [7, 8, 9], 'b': [4, 5, 6]}
>>>> writer = csv.writer(sys.stdout)
>>>> writer.writerow(data.keys())
> a,c,b
>>>> writer.writerows(zip(*data.values()))
> 1,7,4
> 2,8,5
> 3,9,6

--
-dave----------------------------------------------------------------
"Pseudo-colored pictures of a person's brain lighting up are
undoubtedly more persuasive than a pattern of squiggles produced by a
polygraph.  That could be a big problem if the goal is to get to the
truth."  -Dr. Steven Hyman, Harvard



_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Peter Otten
David Perlman wrote:

> Oh, except one problem: the csv.DictWriter lets you tell it what order
> you want the columns output in.  With your version, they just show up
> in whatever order Python wants them.

That's not hard to fix:

>>> fieldnames = "abca"
>>> cols = [data[fn] for fn in fieldnames]
>>> writer.writerows(zip(*cols))
1,4,7,1
2,5,8,2
3,6,9,3

Peter

_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Steven D'Aprano-8
In reply to this post by Matthew Wood-6
On Fri, 28 May 2010 12:00:46 pm Matthew Wood wrote:

> I THOUGHT the guaranteed same-ordering of dict.keys and dict.values
> started in python 2.6.  That was a simple mistake.
>
> It turns out, that's not the case.  But in general, access to dicts
> and sets is unordered, so you can't/don't/shouldn't count on
> ordering.

You can't count on getting a *specific* order, but you can count on
getting a *consistent* order. (So long as you don't modify the
dictionary between calls, of course.)


> The solution to take keys and values from dict.items()
> DOES guarantee their ordering, even if dict.keys and dict.values
> aren't.

And so does zip(d.keys(), d.values()). They both guarantee the same
consistent ordering.

The fact is, yes, your solution does work, but your rationale for
preferring it is irrational. That's not meant to be insulting, we all
have preferences based on irrational little quirks, we wouldn't be
human otherwise. When there are two equally good solutions, you have to
pick one or the other for essentially an irrational reason -- if there
was a rational reason to prefer one over the other, they wouldn't be
equally good.

If you choose to continue using the dict.items() solution, by all means
do so because you like it, or because it gives you a warm fuzzy
feeling, or because it's easier for you to remember. Or because you've
profiled it and it is 3% faster or uses 1% less memory (I made those
numbers up, by the way). These are all good reasons for choosing a
solution over another solution.

But stop trying to justify it on the basis of it being safer and more
backwards compatible, because that's simply not correct. That's what
pushes your solution out of personal preference to cargo-cult
programming: following the form without understanding the semantics.
The semantics of dict.keys() and values() guarantee the same order.


[...]
> But imagine if that guaranteed behavior started in 2.5 for example.
> Then, if you want your code to work on 2.3, you'd definitely want to
> pull them out of the dict via dict.items().

But it didn't start in 2.5. It has been part of Python essentially
forever. If I argued, "Imagine that dictionaries only gained an items()
method in 2.5, and you wanted it to work in 2.3, you'd need to avoid
dict.items()", what would you say?


> I think your response was quite rude.

If you can't take constructive criticism without getting offended and
crying "oh how rude!", there's a serious problem.


> I mean really, cargo cult programming?
> I just tried to suggest a solution and I think it's crappy that you
> accused me of "programming without understanding what you are doing".

I think it is quite clear that in *this* specific case you don't
understand what you are doing, because you are recommending a solution
that you labelled "This line isn't necessary". If it's not necessary,
why include it?

We all code badly at times. I'm sure if you were to go through my code
line by line, you'd find some real clangers caused by me failing to
fully understand what I was doing too. Patches and bug reports are
welcome :)

If it makes you feel any better, I was once told by Alex Martelli (one
of the Python demi-gods) that if he were marking my code for an
assignment he would fail me over what I believed was a trivial
stylistic difference of opinion. I was declaring globals even if I
didn't assign to them, e.g.:

def func(x):
    global y
    return x + y

It took me a long time, perhaps a few years, but I've come around to
Martelli's position on globals and no longer declare them unless I
assign to them. I still think a fail over such a small issue is awfully
harsh, but perhaps he was having a bad day. I've come to understand the
semantics of the global statement better, and can see that unnecessary
global declarations goes against the purpose and meaning of the
statement. I was, in short, cargo-cult programming, using global
without understanding it. As harsh as Martelli's response was, I
believe I'm a better coder today because of it than if he had just
patted me on the head and said "that's okay, you write anything you
like".



--
Steven D'Aprano
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Karl Jansson
I was trying to build python, and this printed to the terminal:

Python build finished, but the necessary bits to build these modules were not found:
_gdbm              ossaudiodev        readline        
spwd                                                  
To find the necessary bits, look in setup.py in detect_modules() for the module's name.



I'm new to python, so i don't know if this is important, or what it means at all.  I looked in setup.py, and it didn't tell me anything.  What does it mean by "the necessary bits" were not found?
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Luke Paireepinart
> I'm new to python, so i don't know if this is important, or what it means at all.  I looked in setup.py, and it didn't tell me anything.  What does it mean by "the necessary bits" were not found?

Not really sure, but in the future please create a new e-mail to
[hidden email] rather than hijacking a thread.  And don't just hit
"reply" and delete the contents of a different e-mail, you have to
create an entirely new message.  Otherwise your message will get
threaded with that other message's thread in certain e-mail clients.
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [Tutor] list of dicts <-> dict of lists?

Matthew Wood-6
In reply to this post by Steven D'Aprano-8

On Fri, May 28, 2010 at 6:55 PM, Steven D'Aprano <[hidden email]> wrote:
On Fri, 28 May 2010 12:00:46 pm Matthew Wood wrote:

> I THOUGHT the guaranteed same-ordering of dict.keys and dict.values
> started in python 2.6.  That was a simple mistake.
>
> It turns out, that's not the case.  But in general, access to dicts
> and sets is unordered, so you can't/don't/shouldn't count on
> ordering.

You can't count on getting a *specific* order, but you can count on
getting a *consistent* order. (So long as you don't modify the
dictionary between calls, of course.)


> The solution to take keys and values from dict.items()
> DOES guarantee their ordering, even if dict.keys and dict.values
> aren't.

And so does zip(d.keys(), d.values()). They both guarantee the same
consistent ordering.

The fact is, yes, your solution does work, but your rationale for
preferring it is irrational. That's not meant to be insulting, we all
have preferences based on irrational little quirks, we wouldn't be
human otherwise. When there are two equally good solutions, you have to
pick one or the other for essentially an irrational reason -- if there
was a rational reason to prefer one over the other, they wouldn't be
equally good.

If you choose to continue using the dict.items() solution, by all means
do so because you like it, or because it gives you a warm fuzzy
feeling, or because it's easier for you to remember. Or because you've
profiled it and it is 3% faster or uses 1% less memory (I made those
numbers up, by the way). These are all good reasons for choosing a
solution over another solution.

But stop trying to justify it on the basis of it being safer and more
backwards compatible, because that's simply not correct. That's what
pushes your solution out of personal preference to cargo-cult
programming: following the form without understanding the semantics.
The semantics of dict.keys() and values() guarantee the same order.


[...]
> But imagine if that guaranteed behavior started in 2.5 for example.
> Then, if you want your code to work on 2.3, you'd definitely want to
> pull them out of the dict via dict.items().

But it didn't start in 2.5. It has been part of Python essentially
forever. If I argued, "Imagine that dictionaries only gained an items()
method in 2.5, and you wanted it to work in 2.3, you'd need to avoid
dict.items()", what would you say?


> I think your response was quite rude.

If you can't take constructive criticism without getting offended and
crying "oh how rude!", there's a serious problem.


> I mean really, cargo cult programming?
> I just tried to suggest a solution and I think it's crappy that you
> accused me of "programming without understanding what you are doing".

I think it is quite clear that in *this* specific case you don't
understand what you are doing, because you are recommending a solution
that you labelled "This line isn't necessary". If it's not necessary,
why include it?

We all code badly at times. I'm sure if you were to go through my code
line by line, you'd find some real clangers caused by me failing to
fully understand what I was doing too. Patches and bug reports are
welcome :)

If it makes you feel any better, I was once told by Alex Martelli (one
of the Python demi-gods) that if he were marking my code for an
assignment he would fail me over what I believed was a trivial
stylistic difference of opinion. I was declaring globals even if I
didn't assign to them, e.g.:

def func(x):
   global y
   return x + y

It took me a long time, perhaps a few years, but I've come around to
Martelli's position on globals and no longer declare them unless I
assign to them. I still think a fail over such a small issue is awfully
harsh, but perhaps he was having a bad day. I've come to understand the
semantics of the global statement better, and can see that unnecessary
global declarations goes against the purpose and meaning of the
statement. I was, in short, cargo-cult programming, using global
without understanding it. As harsh as Martelli's response was, I
believe I'm a better coder today because of it than if he had just
patted me on the head and said "that's okay, you write anything you
like".



--
Steven D'Aprano
_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Well, since it appears that my offer to nip the email flame-war in the bud was declined, I'll reluctantly respond.

And as name dropping Alex Martelli seems the order of the day, I'll go ahead and share my experience with him as well: He decided to put my code into the python cook book (for those that demand citations: Python Cookbook, 1st edition, recipe 2.7, page 49).  He did so while making suggestions on how my code could be improved in many ways, including efficiency and correctness.  He made those suggestions in a very professional, and classy manner, as can be seen in the text of the book.

That's all I'm really asking for here.  I'm 100% sure I made a version-reference mistake.  I'm also 100% sure you recognized that I made a version-reference mistake.  Neither of those facts are in dispute here.  In fact, it's very important, in the context of a tutoring medium like this email list, that someone point out the mistakes made by others.  In other words, constructive criticism is extremely important and very appropriate here, and indeed most every situation.  I both give and receive constructive criticism on a daily if not hourly basis.

But your response was neither professional, nor classy.  At the very least, it was over the top.  Nowhere in Alex's response to me did he insult me, accuse me of "cargo-cult programming" or "programming without understanding what I'm doing", nor use any other insulting/diminishing phrase.  He simply mentioned the ways my code could/should be improved, and showed a better example.

In conclusion, I've remembered the "dress, sort, undress" idiom for sorting data by attribute ever since.  So yes, even when someone is classy, professional, and dare I say nice, messages are be learned.


I hope you have a great weekend. 

--  Matthew Wood

I enjoy haiku
but sometimes they don't make sense;
refrigerator?




_______________________________________________
Tutor maillist  -  [hidden email]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Loading...