473,563 Members | 2,568 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Creating a List of Empty Lists

Pythons internal 'pointers' system is certainly causing me a few
headaches..... When I want to copy the contents of a variable I find
it impossible to know whether I've copied the contents *or* just
created a new pointer to the original value....

For example I wanted to initialize a list of empty lists....

a=[ [], [], [], [], [] ]

I thought there has to be a *really* easy way of doing it - after a
bit of hacking I discovered that :
a = [[]]*10 appeared to work

however - using it in my program called bizarre crashes....
I eventually discovered that (as a silly example) :
a = [[]]*10
b=-1
while b < 10:
b += 1
a[b] = b
print a

Produced :
[ [9], [9], [9]......

Which isn't at all what I intended....... ........
What is the correct, quick way of doing this (without using a loop and
appending...) ?

Fuzzyman

http://www.Voidspace.org.uk
The Place where headspace meets cyberspace. Online resource site -
covering science, technology, computing, cyberpunk, psychology,
spirituality, fiction and more.

---
http://www.atlantibots.org.uk
http://groups.yahoo.com/group/atlantis_talk/
Atlantibots - stomping across the worlds of Atlantis.
---
http://www.fuchsiashockz.co.uk
http://groups.yahoo.com/group/void-shockz
---

Everyone has talent. What is rare is the courage to follow talent
to the dark place where it leads. -Erica Jong
Ambition is a poor excuse for not having sense enough to be lazy.
-Milan Kundera
Jul 18 '05 #1
23 40601
mi*****@foord.n et (Fuzzyman) wrote in
news:80******** *************** ***@posting.goo gle.com:
I eventually discovered that (as a silly example) :
a = [[]]*10
b=-1
while b < 10:
b += 1
a[b] = b
print a

Produced :
[ [9], [9], [9]......

Which isn't at all what I intended....... ........
What is the correct, quick way of doing this (without using a loop and
appending...) ?


The recommended way these days is usually:

a = [ [] for i in range(10) ]

That still has a loop and works by appending empty lists, but at least its
just a single expression. Also you can incorporate the next stage of your
initialisation quite easily:

a = [ [b] for b in range(10) ]

--
Duncan Booth du****@rcp.co.u k
int month(char *p){return(1248 64/((p[0]+p[1]-p[2]&0x1f)+1)%12 )["\5\x8\3"
"\6\7\xb\1\x9\x a\2\0\4"];} // Who said my code was obscure?
Jul 18 '05 #2
Fuzzyman wrote:
Pythons internal 'pointers' system is certainly causing me a few
headaches..... When I want to copy the contents of a variable I find
it impossible to know whether I've copied the contents *or* just
created a new pointer to the original value....

For example I wanted to initialize a list of empty lists....

a=[ [], [], [], [], [] ] [...] What is the correct, quick way of doing this (without using a loop and
appending...) ?


l = [ [] for i in xrange (3)]
l [[], [], []] l [0].append ('a')
l

[['a'], [], []]

Daniel

Jul 18 '05 #3
mi*****@foord.n et (Fuzzyman) wrote:
Pythons internal 'pointers' system is certainly causing me a few
headaches... .. When I want to copy the contents of a variable I find
it impossible to know whether I've copied the contents *or* just
created a new pointer to the original value....

For example I wanted to initialize a list of empty lists....

a=[ [], [], [], [], [] ]

I thought there has to be a *really* easy way of doing it - after a
bit of hacking I discovered that :
a = [[]]*10 appeared to work

however - using it in my program called bizarre crashes....
I eventually discovered that (as a silly example) :
a = [[]]*10
b=-1
while b < 10:
b += 1
a[b] = b
print a

Produced :
[ [9], [9], [9]......

Which isn't at all what I intended....... ........
What is the correct, quick way of doing this (without using a loop and
appending... ) ?


Here it produced an IndexError. After changing "b < 10" into "b < 9"
the code produced:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

I see some other posters already gave you the answer. I'll do
something different and give you the question :-)

n = 4
agents = [[]]*n
print agents
agents[0].append('Smith' )
print agents
neos = map(list,[[]]*n)
print neos
neos[0].append('Neo')
print neos

output is:

[[], [], [], []]
[['Smith'], ['Smith'], ['Smith'], ['Smith']]
[[], [], [], []]
[['Neo'], [], [], []]

The question is:

Why is "Smith" copied to all elements in the matrix?

(or is that another movie :-)

Anton

Jul 18 '05 #4
>>>>> "Anton" == Anton Vredegoor <an***@vredegoo r.doge.nl> writes:

Anton> Why is "Smith" copied to all elements in the matrix?

:)

The construct

[[]] * n

gives you a list with n references to the same list. When you modify
one of the elements, all the references will see the changes.

You can use one of the three (there are more)

([[]]*n)[:]
[[] for _ in range(n)]
map (lambda _: [], range(n))

to get n different copies of [].

Sam
--
Samuel Tardieu -- sa*@rfc1149.net -- http://www.rfc1149.net/sam
Jul 18 '05 #5
Samuel Tardieu wrote:
You can use one of the three (there are more)

([[]]*n)[:]


This won't work. [:] makes a shallow copy. This will make a different
containing list, but the contained lists will still be identical:
s = [[]]*10
s = [[]]*5
t = s[:]
id(s) 1076779980 id(t) 1076780300 map(lambda (x, y): x is y, zip(s, t)) [True, True, True, True, True] s[0].append(2)
s [[2], [2], [2], [2], [2]] t

[[2], [2], [2], [2], [2]]

--
Erik Max Francis && ma*@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \
\__/ I'm sharing the joy / I'm glowing like sunshine
-- Chante Moore
Jul 18 '05 #6
Fuzzyman wrote in message
<80************ **************@ posting.google. com>...
Pythons internal 'pointers' system is certainly causing me a few
headaches... .. When I want to copy the contents of a variable I find
it impossible to know whether I've copied the contents *or* just
created a new pointer to the original value....

You don't need to divine the rules for copy vs. reference: Python NEVER
copies values, ONLY dereferences names, unless you EXPLICITLY ask for a copy
(which Python-the-language doesn't have any special machinery for; you have
to use the copy module or figure out how to copy the object yourself.)

It would help if you stopped thinking in terms of variables and pointers (as
in C) and thought instead in terms of names and objects. Python doesn't
have variables in the C sense, where the variable name stands for its value
ONLY up to the compilation stage, at which time the variable names cease to
exist. Rather, in Python, a "variable" is a name which points to an object.
This behavior is implemented as a key:value pair in a dictionary (i.e.,
__dict__), where the key is a string holding the name and the value is the
object itself. A Python "pointer" is a sort of indexed name, like C arrays;
hence the square-bracket syntax. However, even though the name is strictly
speaking unnamed (i.e., there is no corresponding string object in the
namespace dictionary), yet it is still purely a referent to a real object,
and not a real object itself.

Another way to interpret "pointer" in a Pythonic framework is to say its a
weak-reference: i.e., a reference to an object which does not increase that
object's reference count. However, there is no clear correspondence between
C's "variable/pointer" concepts and what Python does, only analogy.

When no names point to a given object, that object is a candidate for
garbage collection.

All these concepts are illustrated in the following two lines:
[[]]*2 [[], []]

This means:

- Create an empty list.
- Create a list which references that empty list.
- Create an integer '2'. (This step may be optimized away by pre-created
integer objects; pre-creating an object is called "interning" it--these
objects are immortal. You can make one with the intern() builtin.)
- Call the __mul__ method of the one-element list, with an argument of 2.
- The __mul__ method creates a new list, and inserts references to its own
elements into this new list--twice. References/names can *only* be copied
(by definition), not pointed to.
- __mul__ then returns the new list.
- This new list is not bound to any name, and so the object is impossible to
access. It is now a candidate for garbage collection.

So, in this one line, four objects were created and destroyed, not five.

The following behavior should now make sense:
L = [[]]*2
L [[], []] L[0].append(1)
L [[1], [1]]

L[0] and L[1] are two different names, but the object they both point to has
been modified. However:
L[0] = 1
L

[1, [1]]

Here, the name L[0] was made to point to a new object, the integer 1.

The only mutable objects you usually have to worry about are dicts and
lists.

--
Francis Avila

Jul 18 '05 #7
"Francis Avila" <fr***********@ yahoo.com> wrote in message news:<vs******* *****@corp.supe rnews.com>...
Fuzzyman wrote in message
<80************ **************@ posting.google. com>...
Pythons internal 'pointers' system is certainly causing me a few
headaches... .. When I want to copy the contents of a variable I find
it impossible to know whether I've copied the contents *or* just
created a new pointer to the original value....

You don't need to divine the rules for copy vs. reference: Python NEVER
copies values, ONLY dereferences names, unless you EXPLICITLY ask for a copy
(which Python-the-language doesn't have any special machinery for; you have
to use the copy module or figure out how to copy the object yourself.)

[snip...] Interesting discussion reluctantly snipped.......
The only mutable objects you usually have to worry about are dicts and
lists.


Right - because if I do something like :

a = 4
b = a
a = 5
print b

It prints 4... not 5.
In other words - the line b = a creates a name pointing to the object
4, rather than a name pointing to the contents of a.....

I think I see what you mean - since the object 4 is immutable......
the line a = 5 destroys the old name a and creates a new one pointing
to object 5, rather than changing what the name a is pointing to.

Since lists and dictionaries are mutable..... changing the contents
modifies the object rather than destroying the refereence tothe old
one and creating a new one.....

Hmmmmmm... thanks.........

Fuzzy
Jul 18 '05 #8
Right - because if I do something like :

a = 4
b = a
a = 5
print b

It prints 4... not 5.
In other words - the line b = a creates a name pointing to the object
4, rather than a name pointing to the contents of a.....


There's no difference between "the object 4" and "the contents of a", so the
"rather than" makes no sense in this context.

After executing

b = a

the names "a" and "b" refer to the same object.
Jul 18 '05 #9
r.e.s. <r.*@XXmindspri ng.com> wrote:
"David M. Cooke" wrote ...
"r.e.s." wrote:
> But something's wrong with that explanation, because
> of the following:
>
> >>> a = 'gobble'
> >>> a is 'gobble'
> True
>
> Surely `'gobble'` is not the name of an already-existing
> object, so I expected exactly the same result as for
> `100` and `[]`. What's going on there?


Actually, your second use of 'gobble' *is* an already-existing object.
Python 'interns' string constants, i.e., reuses them.

<snip>

Thanks. That explains it.


But take note that this behavior is not guaranteed anywhere in the language
reference. As someone else said in this thread, don't count on interning.
Sometimes it will happen, and sometimes it won't:
a = 'gobble'
a is gobble True b = 'foo bar'
b is 'foo bar'

False

The rule of thumb is that Python interns a string if it's likely to be used
as a name (i.e., only alphanumerics and underscores). The string 'foo bar'
has a space and would be an invalid name, so it wasn't interned.

--
Robin Munn
rm***@pobox.com
Jul 18 '05 #10

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

Similar topics

21
4295
by: Hilde Roth | last post by:
This may have been asked before but I can't find it. If I have a rectangular list of lists, say, l = ,,], is there a handy syntax for retrieving the ith item of every sublist? I know about for i in l] but I was hoping for something more like l. Hilde
3
10785
by: Uwe Ziegenhagen | last post by:
Hi folks, one question: I try to create a list of lists, using std::list<std::list> testlist; but BCC 6 complains:
10
1967
by: Peter Kleiweg | last post by:
This does not what I want it to do: >>> a = ] * 6 >>> a.append('X') >>> a , , , , , ] This does what I want: >>> b = for _ in range(6)]
11
8755
by: JJLaRocque | last post by:
Hi all, Is there a simple python function to return the list index of the minimum entry in a list of lists? ie, for , , ] to return 2,4. Or, same question but just for a list of numbers, not a list of lists. Thanks, Josh
16
2578
by: Michael M. | last post by:
How to find the longst element list of lists? I think, there should be an easier way then this: s1 = s2 = s3 = if len(s1) >= len(s2) and len(s1) >= len(s3): sx1=s1 ## s1 ist längster
7
2176
by: apotheos | last post by:
I can't seem to get this nailed down and I thought I'd toss it out there as, by gosh, its got to be something simple I'm missing. I have two different database tables of events that use different schemas. I am using python to collate these records for display. I do this by creating a list of lists that look roughly like this: events = ,...
16
3640
by: agent-s | last post by:
Basically I'm programming a board game and I have to use a list of lists to represent the board (a list of 8 lists with 8 elements each). I have to search the adjacent cells for existing pieces and I was wondering how I would go about doing this efficiently. Thanks
9
4931
by: Paulo da Silva | last post by:
Hi! What is the best way to have something like the bisect_left method on a list of lists being the comparision based on an specified arbitrary i_th element of each list element? Is there, for lists, something equivalent to the __cmp__ function for classes? Thanks.
19
8592
by: Dr Mephesto | last post by:
Hi! I would like to create a pretty big list of lists; a list 3,000,000 long, each entry containing 5 empty lists. My application will append data each of the 5 sublists, so they will be of varying lengths (so no arrays!). Does anyone know the most efficient way to do this? I have tried: list = ,,,,] for _ in xrange(3000000)]
0
7579
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...
0
7876
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. ...
0
8101
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...
1
7630
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7941
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...
1
5479
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...
0
5201
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3628
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...
0
3612
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.