2

Let us say we have a list of integers:

list = [6, 4, 1, 4, 4, 4, 4, 4, 2, 1]

I now wrote a function which returns another list with all the integers from the list above without repeats.

def no_repeats(s):
    new_list = []
    for number in s:
        if new_list.count(number) < 1:
            new_list.append(number)
    return(new_list)

The new_list returns [6, 4, 1, 2] which is good! My question is how I would now write two similar functions:

A function clean(s) which does not return a new list like the function above, but changes the original list by deleting all the numbers that repeat. Thus, the result has to be the same and the function must not include "return" or create a new list. It must only clean the original list.

A function double(s) which, again, changes the original list (does not return a new list!) but this time, by doubling every number in the original list. Thus, double(list) should change the original list above to:

[6, 6, 4, 4, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1]

Thank you for all the help!

bodhi_kev
  • 121
  • 1
  • 7

2 Answers2

2

Removing duplicates inplace without preserving the order:

def no_repeats(L):
    L[:] = set(L)

There are several variations possible (preserve order, support non-hashable items, support item that do not define total ordering) e.g., to preserve order:

from collections import OrderedDict

def no_repeats(L):
    L[:] = OrderedDict.fromkeys(L)

To double each element's value inplace:

def double(L):
    for i in range(len(L)):
        L[i] *= 2

To duplicate each element:

def duplicate_elements(L):
    L[:] = [x for x in L for _ in range(2)]
jfs
  • 399,953
  • 195
  • 994
  • 1,670
1
>>> def clean(s):
...     s[:] = [s[i] for i in range(len(s)) if s[i] not in s[:i]]
... 
>>> st = [1, 2, 3, 2, 1]

>>> clean(st)
>>> st
[1, 2, 3]

>>> def double(s):
...     s[:] = [s[i//3] for i in range(3*len(s)) if i % 3]
... 
>>> st = [1, 2, 3, 2, 1]
>>> double(st)
>>> st
[1, 1, 2, 2, 3, 3, 2, 2, 1, 1]

neither is particularly efficient nor pythonic, yet do address the OP question

def double(s): ... s[:] = [s[i//2] for i in range(2*len(s))]

will also do the trick, with a little less obsfucation

ShpielMeister
  • 1,417
  • 10
  • 23
  • This is quite an interesting code ShpielMeister! Thank you so much. Could you maybe elaborate what you did in the second function? I would like to learn what you did. :) – bodhi_kev Dec 05 '17 at 20:07
  • 1
    well as an expediancy we just needed to run thru the list 'slowly'. could simply even further. the i//2 will give the same result whether i is 4 or 5. i'll add to the answer – ShpielMeister Dec 05 '17 at 20:13