Move an item inside a list?
Use the insert
method of a list:
l = list(...)
l.insert(index, item)
Alternatively, you can use a slice notation:l[index:index] = [item]
If you want to move an item that's already in the list to the specified position, you would have to delete it and insert it at the new position:l.insert(newindex, l.pop(oldindex))
Move an element in a list
You mean, like, changing C and the dot position? You could have something like:
list_ = [A, B, C, ., D]
list_[2], list_[3] = list_[3], list_[2]
The list_ would look like [A, B, ., C, D]. How to move an Item inside a list of lists?
A list of lists is clunky for representing a matrix. Instead you can use an actual matrix-like type, the NumPy ndarray. NumPy includes a roll()
function that can be used to translate a shape, so you just need to supply the directions.
Firstly, I'll use 0 and 1 for better readability.
import numpy as np
space = np.array([
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 0],
])
Then we can roll it right:>>> np.roll(space, 1, 1)
[[0 0 1 1]
[0 0 1 0]
[0 0 1 0]
[0 0 0 0]]
To do other directions, you just need to supply the right values, and you can wrap that up in a function like this:def move_shape_in_array(array, direction):
directions = {
"up": (-1, 0),
"left": (-1, 1),
"down": (1, 0),
"right": (1, 1),
}
shift, axis = directions[direction]
return np.roll(array, shift=shift, axis=axis)
>>> move_shape_in_array(space, "right")
[[0 0 1 1]
[0 0 1 0]
[0 0 1 0]
[0 0 0 0]]
But this doesn't guard against the shape going off the edge. Instead it wraps around:
>>> move_shape_in_array(space, "up")
[[0 1 0 0]
[0 1 0 0]
[0 0 0 0]
[0 1 1 0]]
To actually guard against it, check if there are any 1s on the edge before moving:edge_idx = 0 if shift == -1 else -1
edge = array[edge_idx] if axis == 0 else array[:, edge_idx]
if edge.any():
return array
(Insert this between the shift, axis =
and return
lines in the function above.) Move items in list from front to the back
Use slicing of list:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
>>> idx = a.index(7)
>>> a = a[idx:] + a[:idx]
>>> a
[7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6]
Note that this will throw a ValueError
if the value being searched is not found in the array, in which case you will need to capture it using try
-except
block Moving a sublist of items in a list to a new position
Consider I
the item to move, J
the next adjacent item and N
your target idx
Two cases:
- case 1: item is before
N
I|J| | | |N
J| | | |N|I
All your elements between I+1
and N
(included) are translated to the left- case 2: item is after
N
N| | | |I|J
N|I| | | |J
All the elements between N+1
and I-1
are translated to the right.At this point an approximate pseudocode (about the indices) looks like:
while el = L.pop()
moveItem(el, N)
if el < N
for all indices of L > el and el < N
indices--
else
for all indices of L < el and > N
indices++
N+=1 #target our last elem
Below a (supposed) proper implem
def move_item(lst, src, dst):
print('move ', src, dst)
el = lst.pop(src)
lst.insert(dst, el)
def move_items(arr, indices, N):
while(len(indices)):
el = indices.pop(0)
if el == N:
#our elem is in place
#target is the elem after
N += 1
continue
if el < N:
#pop effect
N -=1
#insert the elem after N (
move_item(arr, el, N)
for j in range(len(indices)):
el2 = indices[j]
if el2 > el and el2 <= N:
indices[j] -= 1
else:
move_item(arr, el, N)
for j in range(len(indices)):
el2 = indices[j]
if el2 > N and el2 < el:
indices[j] += 1
#we have inserted an elem after N
#next target is our last elem
N += 1
print('now', arr, 'indices', indices)
move_items([0,1,2,3,4,5,6,7,8,9,10,11,12], [8,2,7,4,0],6) #[1, 3, 5, 8, 2, 7, 4, 0, 6, 9, 10, 11, 12]
move_items([0,1,2,3,4,5,6,7,8,9,10,11,12], [8,2,7,4,0,10],6) #[1, 3, 5, 8, 2, 7, 4, 0, 10, 6, 9, 11, 12]
move_items([0,1,2,3,4,5,6,7,8,9,10,11,12], [1,10,5,7,3,8],6) #[0, 2, 3, 4, 1, 10, 5, 6, 7, 8, 9, 11, 12]
Generic List - moving an item within the list
I know you said "generic list" but you didn't specify that you needed to use the List(T) class so here is a shot at something different.
The ObservableCollection(T) class has a Move method that does exactly what you want.
public void Move(int oldIndex, int newIndex)
Underneath it is basically implemented like this.T item = base[oldIndex];
base.RemoveItem(oldIndex);
base.InsertItem(newIndex, item);
So as you can see the swap method that others have suggested is essentially what the ObservableCollection does in it's own Move method. UPDATE 2015-12-30: You can see the source code for the Move and MoveItem methods in corefx now for yourself without using Reflector/ILSpy since .NET is open source.
Move Item to front of list when using for in loop
Modifying a list while iterating over it, is generally not recommended, that said:
>>> ctr = 0
>>> lst = [1,2,3,4,5,6]
>>> for i in lst:
...: if ctr == 3:
...: lst.insert(0,lst.pop(ctr))
...: break
...: ctr += 1
...:
>>> lst
[4, 1, 2, 3, 5, 6]
Or,>>> lst = [1,2,3,4,5,6]
>>> for i,x in enumerate(lst):
... if x == 3:
... lst.insert(0,lst.pop(i))
... break
>>> lst
[3, 1, 2, 4, 5, 6]
Related Topics
Python - Datetime with Timezone to Epoch
Overriding the Save Method in Django Modelform
Understanding the Python with Statement and Context Managers
How to Strip All Whitespace from String
Stop Matplotlib Repeating Labels in Legend
Running Multiple Bash Commands with Subprocess
Reading Tar File Contents Without Untarring It, in Python Script
Multiprocessing.Pool Makes Numpy Matrix Multiplication Slower
How to Frame Two for Loops in List Comprehension Python
Brew Installation of Python 3.6.1: [Ssl: Certificate_Verify_Failed] Certificate Verify Failed
When Should an Attribute Be Private and Made a Read-Only Property
How to Check Task Status in Celery
Regex for Existence of Some Words Whose Order Doesn't Matter
Dump to JSON Adds Additional Double Quotes and Escaping of Quotes
Changing the Options of a Optionmenu When Clicking a Button
Time Complexity of String Concatenation in Python