I want to have a functionality like below. I have tried many things but still unable to achieve it.
>>> a, b = [1], [2]
>>> k = [a, a, b]
>>> k
[[1], [1], [2]]
Now as expected, if I change the second value the first value will be changed automatically.
>>> k[0][0] = 3
>>> k
[[3], [3], [2]]
You see how changing one value affects the other.
Now I want to somehow link the third element with the first two such that whenever I change any of the three elements, every element that it's linked to changes. I want to have the following behavior:
>>> *Do something to link k[1] or k[0] with k[2]*
>>> k[-1][0] = 4
>>> k
>>> [[4], [4], [4]]
I have tried doing the following and failed as you can see below:
>>> b = a
>>> k
>>> [[3], [3], [2]]
Please help me achieve the above.
The real problem I want to solve:
I am implementing min-cut algorithm. In this algorithm I need to merge two vertices at every step. I am trying doing this by linking the two vertices together which I want to merge.
Is this what you want?
a,b = [1],[2]
k = [a,a,b] # store references to lists a and b
print(k)
k[0][0] = 3 # change the first cell's list's first element
print(k) # second cell changes as well since it references same list
k[-1] = k[0] # store the first cell's reference in the last cell. All reference the same list 'a' now.
k[1][0] = 4
print(k)
Output:
[[1], [1], [2]]
[[3], [3], [2]]
[[4], [4], [4]]
Related
I am having a scope issue, and I know how I would solve this in Java, but Python is giving me some issues. Say I have a code as follows:
a = 1
b = 2
c = 3
list1 = [a,b,c]
list2 = [b,c]
b += 1
print list1
print list2
This code does not change the value inside the lists, and there is an easy workaround for the simple example I've given, but the code I am trying to write has 10+ lists that all have different meanings and are used in different ways, but need to communicate with each other and have all the same values for a,b,c. I need to be able to change the variable a,b,c and have all the lists update as well, is there any other way besides writing out the update for each list?
You cannot store the integers by reference, such that incrementing the value in one place causes all other values to be updated. This is because ints are immutable, so changing their value causes a reference change.
>>> a = 5
>>> b = 1
>>> x = [a, b]
>>> id(b)
140508116572264
>>> id(x[1])
140508116572264
>>> b += 1
>>> id(b)
140508116572240
You can see the id of b changes after the increment, so the "b" in the loop and the "b" outside aren't the same.
What you can do, is define a wrapper class for your ints.
class MyInteger:
def __init__(self, value):
self.value = value
Now, build your lists with your MyIntegers:
a = MyInteger(1)
b = MyInteger(2)
c = MyInteger(3)
list1 = [a, b, c]
list2 = [b, c]
Now, when you increment the value of b, you can see the changes are reflected in the lists.
print([x.value for x in list1])
b.value += 1
print([x.value for x in list1])
This prints:
[1, 2, 3]
[1, 3, 3]
I have a list of lists like:
list1=[[1], [2], [3], [4], [5], [6]]
I have to combine lists of lengths given by another list like:
list2=[1, 2, 3]
The final result should be like this: [ [1], [2,3], [4,5,6] ].
How can I proceed to do this?I am using Python 3.6
You can try using an iterator on list1 in a list comprehension over list2:
>>> list1=[[1], [2], [3], [4], [5], [6]]
>>> list2=[1, 2, 3]
>>> v = iter(list1)
>>> [sum((next(v) for _ in range(a)), []) for a in list2]
[[1], [2, 3], [4, 5, 6]]
v is an iterator over list1; next(v) simply returns the next sublist in the list. In the comprehension, a takes on the values in list2, which denote the lengths of the combined lists we want. The sum(...) is what actually takes a sublists (via range(a)) from list1 (via next(v)) and combines them into a single list.
If I have an input like this (1, 2, 3, 4, 5, 6)
The output has to be ... [[1, 2], [3, 4], [5, 6]].
I know how to deal with if it's one element but not two.
x=[]
for number in numbers:
x.append([number])
I'll appreciate your any help!
Something like this would work:
out = []
lst = (1,2,3,4,5,6,7,8,9,10)
for x in range(len(lst)):
if x % 2 == 0:
out.append([lst[x], lst[x+1]])
else:
continue
To use this, just set lst equal to whatever list of numbers you want. The final product is stored in out.
There is a shorter way of doing what you want:
result = []
L = (1,2,3,4,5,6,7,8,9,10)
result = [[L[i], L[i + 1]] for i in range(0, len(L) - 1, 2)]
print(result)
You can use something like this. This solution also works for list of odd length
def func(lst):
res = []
# Go through every 2nd value | 0, 2, 4, ...
for i in range(0, len(lst), 2):
# Append a slice of the list, + 2 to include the next value
res.append(lst[i : i + 2])
return res
# Output
>>> lst = [1, 2, 3, 4, 5, 6]
>>> func(lst)
[[1, 2], [3, 4], [5, 6]]
>>> lst2 = [1, 2, 3, 4, 5, 6, 7]
>>> func(lst2)
[[1, 2], [3, 4], [5, 6], [7]]
List comprehension solution
def func(lst):
return [lst[i:i+2] for i in range(0, len(lst), 2)]
Slicing is better in this case as you don't have to account for IndexError allowing it to work for odd length as well.
If you want you can also add another parameter to let you specify the desired number of inner elements.
def func(lst, size = 2): # default of 2 it none specified
return [lst[i:i+size] for i in range(0, len(lst), size)]
There's a few hurdles in this problem. You want to iterate through the list without going past the end of the list and you need to deal with the case that list has an odd length. Here's one solution that works:
def foo(lst):
result = [[x,y] for [x,y] in zip(lst[0::2], lst[1::2])]
return result
In case this seems convoluted, let's break the code down.
Index slicing:
lst[0::2] iterates through lst by starting at the 0th element and proceeds in increments of 2. Similarly lst[1::2] iterates through starting at the 1st element (colloquially the second element) and continues in increments of 2.
Example:
>>> lst = (1,2,3,4,5,6,7)
>>> print(lst[0::2])
(1,3,5,7)
>>> print(lst[1::2])
(2,4,6)
zip: zip() takes two lists (or any iterable object for that matter) and returns a list containing tuples. Example:
>>> lst1 = (10,20,30, 40)
>>> lst2 = (15,25,35)
>>> prit(zip(lst1, lst2))
[(10,15), (20,25), (30,35)]
Notice that zip(lst1, lst2) has the nice property that if one of it's arguments is longer than the other, zip() stops zipping whenever the shortest iterable is out of items.
List comprehension: python allows iteration quite generally. Consider the statement:
>>> [[x,y] for [x,y] in zip(lst1,lst2)]
The interior bit "for [x,y] in zip(lst1,lst2)" says "iterate through all pairs of values in zip, and give their values to x and y". In the rest of the statement
"[[x,y] for [x,y] ...]", it says "for each set of values x and y takes on, make a list [x,y] to be stored in a larger list". Once this statement executes, you have a list of lists, where the interior lists are all possible pairs for zip(lst1,lst2)
Very Clear solution:
l = (1, 2, 3, 4, 5, 6)
l = iter(l)
w = []
for i in l:
sub = []
sub.append(i)
sub.append(next(l))
w.append(sub)
print w
Given an edge set (a list of lists in python speak) of a hypergraph (e.g. l = [[1,2,3], [2], [3], [3,4]]), the task is to remove all edges which contain a specific vertex (e.g. vertex 2).
For above example, the result should be [[3], [3, 4]].
I have troubles to understand why the first function does not work as expected.
def edge_delete(edge_set, v0):
""" delete all edges containing vertex v0 """
for edge in edge_set:
if v0 in edge:
edge_set.remove(edge)
return edge_set
gives
l = [[1,2,3], [2], [3], [3,4]]
edge_delte(l, 2)
[[2], [3], [3, 4]]
It is not clear to me why element [1,2,3] was removed, but not element [2].
The below gives the correct result
def edge_delete_v2(edge_set, v0):
""" delete all edges containing vertex v0 """
return [edge for edge in edge_set if v0 not in edge]
gives
l = [[1,2,3], [2], [3], [3,4]]
edge_delete_v2(l, 2)
[[3], [3, 4]]
The first code is trying to modify a list as you are iterating through it, which can trip up the iteration.
The second is not modifying the list at all; it is using it to build up a brand new list with the elements that would not get deleted.
I got the following problem:
I'm writing a script for Ensight (a program for visualizing CFD computations) in python.
The program Ensight gives me a list for the time values like:
print ensight.query(ensight.TIMEVALS)['timevalues']
[[0, 0.0], [1, 9.99e-07], [2, 1.99e-06], [3, 0.0003],etc.]
Where the first value in every list is the timestep and the second value the actual time at this timestep. Now I want to ask somehow for timestep '2' and want to know the corresponding second value of the list. Therefore if I could just find the index of the timestep I could easily have the corresponding time value.
EDIT\\
It solved it now like this:
time_values = ensight.query(ensight.TIMEVALS)['timevalues']
for start,sublist in enumerate(time_values):
if step_start in sublist:
index_begin = start
for end,sublist in enumerate(time_values):
if step_stop in sublist:
index_end = end
Maybe this is what you want?
print ensight.query(ensight.TIMEVALS)['timevalues'][1][1]
That should print the 9.99e-07 as it is the second value in the second list included in your main list.
I'm just wondering why you have 3 opening and just 2 closing brackets. Is this a typo?
[[ [..].. ]
If you have a list like myList = [[0, 0.0], [1, 9.99e-07], [2, 1.99e-06], [3, 0.0003],etc.]
you can access the first nested list with myList[0] resulting in [0, 0.0]
To access the second value in that list you can use myList[0][1]
Set n to the required timestep value
>>> n=2
>>> print [list[1] for list in ensight.query(ensight.TIMEVALS)['timevalues'] if list[0]=n ]
this can also be extended in your case
>>> from=2
>>> to=100
>>> print [list[1] for list in ensight.query(ensight.TIMEVALS)['timevalues'] if (list[0]>from && list[0]<to) ]
>>> l = ensight.query(ensight.TIMEVALS)['timevalues']
>>> print l
[[0, 0.0], [1, 9.99e-07], [2, 1.99e-06], [3, 0.0003]]
>>> _d = {int(ele[0]): ele[1] for ele in l}
>>> print _d[2]
1.99e-o6