9

Is it possible to insert to a list when a specific string appears. Example:

List=['north','south','east','west','south','united']

So for every time the string 'south' is presented the list will be insert an item 'canada' before the element south in the list.

Results
List=['north','canada','south','east','west','canada','south','united']

EDIT: I apologize for not being specific enough. I need it to seek the specific characters.

List1=['north','<usa>23<\usa>','east','west','<usa>1942<\usa>','united']
Result=['north','canada', '<usa>23<\usa>','east','west','canada','<usa>1942<\usa>','united']
  • you are looking for `insert`, not `append`. [this question](http://stackoverflow.com/questions/34099329/add-spaces-to-elements-of-list/34099402?noredirect=1#comment55950963_34099402) may help, though you will have to put a conditional statement in your list traversal – R Nar Dec 07 '15 at 20:06
  • Are you sure it is `<\usa>` and not ``? – Willem Van Onsem Dec 07 '15 at 22:16

6 Answers6

12

To be able to place elements within a list in specific positions, you need to list insert function.

<list>.insert(<position>, <value>)

As an example, if you have a list containing the following:

a = [2, 4, 6, 8, 12]

And want to add 10 in the list but maintain the current order, you can do:

a.insert(4, 10)

and will get:

[2, 4, 6, 8, 10, 12]

EDIT

To insert before every 'south' do:

for i in range(len(<list>)):
    if <list>[i] == 'south':
        <list>.insert(i, 'canada')
m_callens
  • 6,100
  • 8
  • 32
  • 54
  • 1
    This does not really answers the question I think? – Willem Van Onsem Dec 07 '15 at 20:10
  • I understand the insert function but for how do I insert it a new element to my list before every element that says 'south' –  Dec 07 '15 at 20:10
  • Do you think the cycle `for i in range(len(..))` could really work? I think you should go backwards, not to move items which are not handled yet. In addition use of `enumerate()` would be nice. – mirek Feb 08 '21 at 11:17
6

Inserting element before another

>>> x = [1,2,3,4,5]
>>> x.insert(x.index(4), 22)
>>> x
[1, 2, 3, 22, 4, 5]

Inserting element after another

>>> x = [1,2,3,4,5]
>>> x.insert(x.index(3)+1, 22)
>>> x
[1, 2, 3, 22, 4, 5]

However, this does not work for multiple insertions

>>> x = [1,2,3,4,5,4,6,4,7]
>>> x.insert(x.index(4), 22)
>>> x
[1, 2, 3, 22, 4, 5, 4, 6, 4, 7]
5

The simple answer:

def blame_canada(old_list): 
    new_list = []
    for each in old_list:
        if each == 'south':
            new_list.append('canada')
        new_list.append(each)
    return new_list
RD3
  • 1,089
  • 10
  • 24
  • 4
    Don't need the `else`; you're appending `each` in either branch, so make it unconditional. – jscs Dec 07 '15 at 20:21
3

You can use a simple one-liner using double list comprehension (using List like you defined it):

>>> [inner for outer in [(['canada',x] if x == 'south' else [x]) for x in List] for inner in outer]
['north', 'canada', 'south', 'east', 'west', 'canada', 'south', 'united']

The answers consists out of two parts:

  • the inner list comprehension: [(['canada',x] if x == 'south' else [x]) for x in List] this iterates over the list and returns a list of lists. In case x is south, it emits ['canada','south'], otherwise it emits [x]. So the result is something like:

    >>> [(['canada',x] if x == 'south' else [x]) for x in List]
    [['north'], ['canada', 'south'], ['east'], ['west'], ['canada', 'south'], ['united']]
    

    for the given list.

  • Next the result is flattened using this approach.

Community
  • 1
  • 1
Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
3

Use a simple loop:

L = ['north','south','east','west','south','united']
res = []
for entry in L:
    if entry == 'south':
        res.append('canada')
    res.append(entry)
L[:] = res

The last line copies the result into the original list. This makes it equivalent to append that modifies the original list. Using a lot of insert calls would make it really slow for large list as it need to build the whole lists for each insert.

Mike Müller
  • 82,630
  • 20
  • 166
  • 161
  • I didn't specify that well but I understand this, I am looking if it contains these letters. Then I would append because on my actually list there will be numbers appended to the seeking element . –  Dec 07 '15 at 20:28
1

Here's a high-performance list-comprehension method for doing this.

First, it generates a list of indexes containing "south".

Then, it uses the index + index-order for the insertion point (to account for previous insertions in the loop), making for a simple, yet quick and easy-to-follow pythonic solution for this problem:

List = ['north','south','east','west','south','united']
souths = [idx for idx, val in enumerate(List) if val == 'south']
for i, idx in enumerate(souths):
    List.insert(idx+i, 'canada')
Steven Moseley
  • 15,871
  • 4
  • 39
  • 50