List Behavior when inserting new items

D

Drew

I'm looking to add an element to list of items, however I'd like to
add it at a specific index greater than the current size:

list = [1,2,3]
list.insert(10,4)

What I'd like to see is something like:

[1,2,3,,,,,,4]

However I see:

[1,2,3,4]

Is there any way to produce this kind of behavior easily?

Thanks,
Drew
 
D

Diez B. Roggisch

Drew said:
I'm looking to add an element to list of items, however I'd like to
add it at a specific index greater than the current size:

list = [1,2,3]
list.insert(10,4)

What I'd like to see is something like:

[1,2,3,,,,,,4]

However I see:

[1,2,3,4]

Is there any way to produce this kind of behavior easily?

Use a dictionary?

If you know how large the list eventually will be, and that each
position is filled, you can also use range(n) to create a list.

What is your actual usecase?

diez
 
D

Drew

What is your actual usecase?

The issue is that I don't know how long the list will eventually be.
Essentially I'm trying to use a 2D list to hold lines that I will
eventually print to the screen. Blank elements in the list will be
printed as spaces. I suppose every time I add an element, I could find
the difference between the size of the list and the desired index and
fill in the range between with " " values, however I just wanted to
see if there was a more natural way in the language.

Thanks,
Drew
 
W

wittempj

I'm looking to add an element to list of items, however I'd like to
add it at a specific index greater than the current size:

list = [1,2,3]
list.insert(10,4)

What I'd like to see is something like:

[1,2,3,,,,,,4]

However I see:

[1,2,3,4]

Is there any way to produce this kind of behavior easily?

Thanks,
Drew

You could write your own class mimicing a list with your desired
behaviour, something like:

py>class llist(object):
py> def __init__(self, arg = []):
py> self.__list = arg
py> def __setitem__(self, key, value):
py> length = len(self.__list)
py> if length < key:
py> for i in range(length, key +1):
py> self.__list.append(None)
py> self.__list[key] = value
py> def __str__(self):
py> return str(self.__list)
py>
py>x = llist()
py>x[10] = 1
py>print x
[None, None, None, None, None, None, None, None, None, None, 1]

for other methods to add to the llist class see http://docs.python.org/
ref/sequence-types.html
 
P

Paul McGuire

py> def __init__(self, arg = []):
py> self.__list = arg

Please don't perpetuate this bad habit!!! "arg=[]" is evaluated at
compile time, not runtime, and will give all default-inited llists the
same underlying list.

The correct idiom is:

def __init__(self, arg = None):
if arg is not None:
self.__list = arg
else:
self.__list = []

-- Paul
 
M

mensanator

Essentially I'm trying to use a 2D list to hold lines that I will
eventually print to the screen. Blank elements in the list will be
printed as spaces. I suppose every time I add an element, I could find
the difference between the size of the list and the desired index and
fill in the range between with " " values, however I just wanted to
see if there was a more natural way in the language.

I would use DBR's suggestion to use a dictionary and only store
actual values. In this example, I'm making a histogram that only
ends up having results for 4,7,8,9,10 but I want the graph to show
the zero occurrences as well, so I just create them on the fly
when printing.

print
print 'tc factor of 2 distribution (* scale = 8)'
print
tchistkeys = tchist.keys()
tchistkeys.sort()
prev_key = 0
for i in tchistkeys:
while prev_key<i:
print '%3d (%3d)' % (prev_key,0)
prev_key += 1
print '%3d (%3d)' % (i,tchist),
hgraph = divmod(tchist,8)
s = '*'*(hgraph[0])
if hgraph[1]>0:
s = s + '.'
print s
prev_key += 1

## tc factor of 2 distribution (* scale = 8)
##
## 0 ( 0)
## 1 ( 0)
## 2 ( 0)
## 3 ( 0)
## 4 ( 1) .
## 5 ( 0)
## 6 ( 0)
## 7 (112) **************
## 8 (219) ***************************.
## 9 ( 58) *******.
## 10 (110) *************.
 
D

Drew

Is there any way to produce this kind of behavior easily?Hints:
[None] * 5 [None, None, None, None, None]
[1, 2, 3, None] + [10]
[1, 2, 3, None, 10]

HTH

That is exactly what I was looking for. I'm actually working on some
problems at http://codgolf.com. I find it helps me to learn a language
and I'm coming from ruby where arrays have subtle differences from
python's lists. Thanks for all the helpful responses.
 
B

Bruno Desthuilliers

Drew a écrit :
I'm looking to add an element to list of items, however I'd like to
add it at a specific index greater than the current size:

list = [1,2,3]

NB: better to avoid using builtins types and functions names as identifiers.
list.insert(10,4)

What I'd like to see is something like:

[1,2,3,,,,,,4]

Hint : the Python representation of nothing is a singleton object named
None.
However I see:

[1,2,3,4]

Yeps. I thought it would have raised an IndexError. But I seldom use
list.insert() to append to a list - there's list.append() (and/or
list.extend()) for this.
Is there any way to produce this kind of behavior easily?
Hints:
>>> [None] * 5 [None, None, None, None, None]
>>> [1, 2, 3, None] + [10]
[1, 2, 3, None, 10]

HTH
 
B

Bruno Desthuilliers

Drew a écrit :
The issue is that I don't know how long the list will eventually be.

How is this an issue ? Python's lists are not fixed-sized arrays.
Essentially I'm trying to use a 2D list to hold lines that I will
eventually print to the screen.
>
Blank elements in the list will be
printed as spaces. I suppose every time I add an element, I could find
the difference between the size of the list and the desired index and
fill in the range between with " " values,

Yes. But note that [1,2,3,' ',' ',4]
is not the same thing as [1,2,3,,,4] (which is not valid Python FWIW).
however I just wanted to
see if there was a more natural way in the language.

I'm not sure I get it. Do you mean you're trying to use a list of lists
as a representation of a 2D matrix (IOW, a bitmap) ? Something like

bpm = [
['X',' ',' ',' ','X'],
[' ','X',' ','X',' '],
[' ',' ','X',' ',' '],
[' ','X',' ','X',' '],
['X',' ',' ',' ','X'],
]

If so, using dicts can be somewhat simpler and less memory-consuming:

d = {1:1, 2:2, 3:3}
d[10] = 4
for i in range(1, max(d.keys())+1):
print d.get(i, ' ')

That is, instead of storing useless spaces for "blank cells" and having
to do math to compute how many of them you have to insert/delete, you
just place stuff at desired indices, and 'fill in' spaces when printing
out to screen.

HTH
 
G

Guest

* Paul McGuire said:
py> def __init__(self, arg = []):
py> self.__list = arg

Please don't perpetuate this bad habit!!! "arg=[]" is evaluated at
compile time, not runtime, and will give all default-inited llists the
same underlying list.

While this actually might be bad habit, the default arguments are *not*
eval'd at compile time. This seems to be a common mistake. They are
evaluated at runtime as everything else. The difference to other local
variables is, that the objects they're referring to are just initalized
once instead of each time they're taken into account.

nd
 
G

Gigs_

I'm looking to add an element to list of items, however I'd like to
add it at a specific index greater than the current size:

list = [1,2,3]
list.insert(10,4)

What I'd like to see is something like:

[1,2,3,,,,,,4]

However I see:

[1,2,3,4]

Is there any way to produce this kind of behavior easily?

Thanks,
Drew

You could write your own class mimicing a list with your desired
behaviour, something like:

py>class llist(object):
py> def __init__(self, arg = []):
py> self.__list = arg
py> def __setitem__(self, key, value):
py> length = len(self.__list)
py> if length < key:
py> for i in range(length, key +1):
py> self.__list.append(None)
py> self.__list[key] = value
py> def __str__(self):
py> return str(self.__list)
py>
py>x = llist()
py>x[10] = 1
py>print x
[None, None, None, None, None, None, None, None, None, None, 1]

for other methods to add to the llist class see http://docs.python.org/
ref/sequence-types.html

or like this
def __init__(self):
list.__init__(self)
def insertatindex(self, index, value):
lenght = len(self)
if lenght < index:
for i in range(lenght, index):
self.append(None)
self.insert(index, value)
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top