1

if i have a list in python were i have a lot of numers example:

list = [1,2,3,12,4,5,23,5,6,56,8,57,8678,345,234,13, .....]

so a list of all integers, that all can have different values ... (i my case this list could be very long, and is actually not an integer list, but a list of Objects which are all from the same type an have a attribute age which is a integer) whats the most efficient way to add all those values by +1 is it

new_list = [x+1 for x in list]

or maybe

new_list = []
for x in list:
    new_list.append(x+1)

(i guess it makes no difference)

or is there maby a more efficent way or an other data sructure to make this more performant? I really wonder if there is not any method, maybe using something different the a list were i can do this operation more efficient because the +1 seems son simple ...

cs95
  • 379,657
  • 97
  • 704
  • 746
man zet
  • 826
  • 9
  • 26
  • 1
    You can try both and time them ;) – Ignacio Vergara Kausel Nov 08 '17 at 14:32
  • 1
    Are they all getting one year older? You might consider storing a birth date instead and make age a property that calculates itself based on the current date. – user2390182 Nov 08 '17 at 14:49
  • @schwobaseggl yes in the mainloop of my programm all are getting one "year" older. You have a interesting idea which would work in some cases, but in mine i have to check in every step of the loop if one of them passed a maxAge and then delete it from the list. So is think to calculate the age every time is not as good ass adding one to everyone ... – man zet Nov 08 '17 at 15:28

3 Answers3

3

If you actually have a list of objects with an integer attribute, as you say, you can update the attribute in-place:

class A(object):
    def __init__(self, x):
        self.x = x

my_list = [A(2), A(5), A(1)]
for obj in my_list:
    obj.x += 1
assert my_list[0].x == 3
assert my_list[1].x == 6
assert my_list[2].x == 2
chepner
  • 497,756
  • 71
  • 530
  • 681
  • thanks but thats what i'm actually doing. I just wanted to simplyfiy the problem. I cant see in which way your approach should be any faster... Or am i missed there something? – man zet Nov 08 '17 at 15:30
  • That's as simple as it gets. It should be a little faster, as you aren't having to create any new objects or lists; you are simply modifying existing objects. – chepner Nov 08 '17 at 15:41
0

There is no fastest way but I think this is an interesting attempt since u never use more RAM than actually needed (u delete the entries once you copied them)

list1 = []
while (len(list) != 0):
    list1.append(list.pop(0)+1)

After receiving a comment I did some testing and found the results very interesting!

Testing results.

  • 2
    This would work, but as the docs mention, `list.pop(0)` is not very efficient, because all the following items in the list have to be moved down. And since you're looping over every list item, you've turned a O(n) problem into a O(n²) problem. – PM 2Ring Nov 08 '17 at 14:47
  • very interesting that the second one is so more effective than the first one. I would have thought that they do exactly the same ... – man zet Nov 08 '17 at 15:24
-1

Try to use map. It must be fast due to some built-in optimizations.

t = [1, 2, 3, 4, 5, 6, 7, 8]
print (map(lambda x:x + 1, t))
  • Not so sure `map` is best in connection with `lambda`: https://stackoverflow.com/questions/1247486/python-list-comprehension-vs-map – user2390182 Nov 08 '17 at 14:43
  • That won't work in Python 3, since `map` returns an iterator, not a list. So in Python 3 you can either wrap the `map` call in `list()`, or unpack the iterator with the `*` splat operator: `print(*map(lambda x:x + 1, t))`. But in both Python 2 & 3 you can make it more efficient by getting rid of that lambda, and directly calling the `__add__` method of the 1 integer object: `print(list(map((1).__add__, t)))` – PM 2Ring Nov 08 '17 at 14:54