Below are my 2 lists:
a: ['a0', 'a3']
b: ['b0', 'b1', 'b0', 'b1']
I need to merge the above 2 list as below:
final: ['a0b0', 'a0b1', 'a3b0', 'a3b1']
Need to write a for loop which will check for "0" in list b and then start with the next element in list a.
Thanks,
If I understand the rules, you need to combine two lists such as:
items from both lists will be combined, items from the first list will come first (e.g. "a0" and "b1" will become "a0b1")
there could be repeating items in both lists but you don't want these repetitions to be present in the final list
I think Python is your best friend here, I'd propose this piece of code as a custom library:
Libraries/ListUtils.py
def combine_lists(list1, list2):
set1 = set(list1)
set2 = set(list2)
final_list = []
for i1 in set1:
for i2 in set2:
final_list.append("{}{}".format(i1, i2))
return final_list
and an example test case:
*** Settings ***
Library ../Libraries/ListUtils.py
Library Collections
*** Test Cases ***
Combine Lists
${list1}= Create List a0 a3
${list2}= Create List b0 b1 b0 b1
${final_list}= Combine Lists ${list1} ${list2}
Log To Console ${final_list}
This will log into console:
['a3b1', 'a3b0', 'a0b1', 'a0b0']
which is the output you specified in your question. It's not ordered in any way, you might want to add this to it.
Also note that there's Combine Lists keyword in Collections library (but this one does something else than you want). As a result of that, my example will produce one warning:
[ WARN ] Keyword 'Combine Lists' found both from a custom test library 'ListUtils' and a standard library 'Collections'. The custom keyword is used. To select explicitly, and to get rid of this warning, use either 'ListUtils.Combine Lists' or 'Collections.Combine Lists'.
So you might want to pay more attention to naming conventions, or call keywords by their full name like e.g. Collections.Combine Lists.
Related
Afternoon-I'm currently trying to read up on/implement more clever ways to form the union of sub lists after imposing varying conditions on the original list (or, more generally, any list)-specifically the successive union over what may be a large number of sublists. the data within may be strings, or numerical data.
For example, I could form sub lists of the following list based on the condition if 'a' appears in the ith position of the list.
mylist = [a b c d
d a b c
c b a d
b d c a]
mysublist1 = [item for item in mylist if item[0] == a]
mysublist = [ a b c d]
In this example, I could repeat this process and change the condition to be the ith position of the list and generate 4 sublists. I could then-for demonstrations sake, reform the original list using the handy set functions
set(thisset).union(thatset)
However, without being clever this will take n-1 instances of these guys (forming the first union, then taking successive unions)-which can get dicey.
Is anyone aware of any methods that would make this a bit more elegant? I have tried appending sets to a list and then defining the successive union over the size of this list be fruitful (but I'm getting some type errors!)
Thanks!
I have two lists, one is a list of lists, and they have the same number of indexes(the half number of values), like this:
list1=[['47', '43'], ['299', '295'], ['47', '43'], etc.]
list2=[[9.649, 9.612, 9.42, etc.]
I want to detect the repeated pair of values in the same list(and delete it), and sum the values with the same indexes in the second list, creating an output like this:
list1=[['47', '43'], ['299', '295'], etc.]
list2=[[19.069, 9.612, etc.]
The main problem is that the order of the values is important and I'm really stuck.
You could create a collections.defaultdict to sum values together, with keys as the sublists (converted as tuple to be hashable)
list1=[['47', '43'], ['299', '295'], ['47', '43']]
list2=[9.649, 9.612, 9.42]
import collections
c = collections.defaultdict(float)
for l,v in zip(list1,list2):
c[tuple(l)] += v
print(c)
Alternative using collections.Counter and which does the same:
c = collections.Counter((tuple(k),v) for k,v in zip(list1,list2))
At this point, we have the related data:
defaultdict(<class 'float'>, {('299', '295'): 9.612, ('47', '43'): 19.069})
now if needed (not sure, since the dictionary holds the data very well) we can rebuild the lists, keeping the (relative) order between them (but not their original order, that shouldn't be a problem since they're still linked):
list1=[]
list2=[]
for k,v in c.items():
list1.append(list(k))
list2.append(v)
print(list1,list2)
result:
[['299', '295'], ['47', '43']]
[9.612, 19.069]
Let me try to put this in a simple manner.
I have 2 lists, which look like below:
List1 = [('a', 1, 'low'), ('b', 10, 'high')] # --> Tuples in List
List2 = ["('a', 1, 'low')", "('b', 10, 'high')"] # --> Here the Tuples are actually of Type String.
List1 is output of a SQL query. List2 is defined by me as expected result.
I am using Robot Framework to compare these two lists with the Keyword Lists Should Be Equal. But it fails as List2 has strings which look like Tuple.
How can I compare these two lists? Can I convert both the lists to a different variable type so that I can compare them. I am trying to avoid the python coding here.
It's unclear exactly what your data looks like, but since the two lists have different contents you'll have to convert one or both of them to a common format.
You could, for example, convert the first list to a string with something like this:
| ${actual}= | Evaluate | [str(x) for x in ${List1}]
I doubt that gives you exactly what you need because, again, it's unclear exactly what you need. However, the technique remains the same: use Evaluate to write a little bit of python code to convert one of your lists to be the same format as the other list before doing the compare.
This may be the long procedure, i have used tuples (1,2) instead (a,1,low) #( cause name error in python). But you told its getting from SQL. Important is difference between (1,2) and (1, 2) #(space mismatch)
var.py
List1 = [(1,2), (3,4)]
test.robot(txt file)
*** Settings ***
Library BuiltIn
Library Collections
Variables var.py
Library String
*** Variables ***
#{appnd_li}
*** Test Cases ***
TEST
#constructing List2=["(1, 2)","(3, 4)"]
${List2}= Create List (1, 2) (3, 4)
# importing List1 from variable file
${len}= Get Length ${List1}
#initialize empty list
${li}= Create List #{appnd_li}
:FOR ${I} IN RANGE 0 ${len}
\ ${item}= Convert To String ${List1[${I}]}
\ Append To List ${li} ${item}
Lists Should Be Equal ${li} ${List2}
~
First I select the group named hairSystem1Follicles and make a list of it
then I make an empty list with things to delete
cmds.select('hairSystem1Follicles',hi=1)
list=cmds.ls(sl=1)
listtodelete=[]
I have tried two things, but both are useless.
I would like it to isolate all the elements in the list with the name curve1 curve2 etc. not # the other things in the list which are named loftfolicle*
attempt 1
for e in list:
if e=='curve*': #Find which ones are Write nodes
listtodelete.append(e)
attempt 2
for e in list:
if 'curve'+'*' in e:
listtodelete.append(e)
neither seem to work out.
I dont know how which functions you use to get your list (i would rename your list, because "list" is the typename of the built-in list), but if your list only contains strings, this code should work:
for e in myList: //renamed list
if e.lower().startswith("curve"):
listtodelete.append(e)
This code checks, if the lowercase version of e starts with "curve", so things like "curve2", "curve4", "CuRvEandsoOn" are appended to listtodelete. If there are any more conditions to check on e, let me know. By the way, if e is no string, maybe because you iterate a list of object, and you get "the name of e" (the actual string to check) by e.g. e.name(), just add this line of code at the beginning of your for loop:
e = e.name() //or something else, if e is no string, but e.name() is
I am new to Haskell and have been trying to pick up the basics.
Assume I have the following list y:
3:3:2:1:9:7:3:[]
I am trying to find a way to delete the first occurrence of 3 in list y. Is this possible using simple list comprehension?
What I tried (this method deletes all instances from a list):
deleteFirst _ [] = []
deleteFirst a (b:bc) | a == b = deleteFirst a bc
| otherwise = b : deleteFirst a bc
No, it's not possible using a list comprehension. In a list comprehension you make a decision which element to keep based on that element only. In your example, you want to treat the first 3 you encounter differently than other 3s (because you only want to remove the first one), so the decision does not depend on the element alone. So a list comprehension won't work.
Your attempt using a recursive function is already pretty close, except that, as you said, it removes all instances. Why does it remove all instances? Because after you removed the first one, you call deleteFirst again on the rest of the list, which will remove the next instance and so on. To fix this, just do not call deleteFirst again after removing the first instance. So just use bc instead of deleteFirst a bc in that case.
as other already mentioned list comprehension is not an appropriate solution to this task (difficult to terminate the execution at one step).
You've almost written the correct solution, just in the case of equality with the matched value you had to terminate the computation by returning the rest of list without the matched element:
deleteFirst _ [] = []
deleteFirst a (b:bc) | a == b = bc
| otherwise = b : deleteFirst a bc
> print $ deleteFirst 3 (3:3:2:1:9:7:3:[])
> [3,2,1,9,7,3]
I don’t believe it is possible to do this with list comprehension (at least not in in any idiomatic way).
Your deleteFirst works almost. All you need to change to fix is is to stop deleting after the first match, i.e. replace deleteFirst a bc in the first clause by bc.
sepp2k's remarks about list comprehensions are an important thing to understand; list operations like map, filter, foldr and so on treat all list items uniformly, and the important thing to understand about them is what information is available at each step, and how each step's result is combined with those of other steps.
But the aspect I want to stress is that I think you should really be trying to solve these problems in terms of library functions. Adapting the solution from this older answer of mine to your problem:
deleteFirst x xs = beforeX ++ afterX
-- Split the list into two pieces:
-- * prefix = all items before first x
-- * suffix = all items after first x
where (beforeX, xAndLater) = break (/=x) xs
afterX = case xAndLater of
[] -> []
(_:xs) -> xs
The trick is that break already has the "up to first hit" behavior built in it. As a further exercise, you can try writing your own version of break; it's always instructive to learn how to write these small, generic and reusable functions.