Comparing lists which consists of tuples using RF - python-2.7

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}
~

Related

Merge 2 lists in robot framework

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.

How to show which values of one list are in other list?

Having 2 lists, I want check which values of List1 are in List2. I'm trying as below but I get error
List1 = {3,2,8,7,5}
List2 = {1,3,4,2,6,7,9}
= List.Transform(List1, each Text.Contains(List2, _))
Expression.Error: We cannot convert a value of type List to type Text.
Details:
Value=[List]
Type=[Type]
My expected output would be 3,2,7.
How can I do this?
See List.Intersect Documentation
Intersect = List.Intersect({List1,List2})
#horseyride has probably the best answer but using your original logic, you could also write the intersection like this:
List.Select(List1, each List.Contains(List2, _))
This uses Select instead of Transform since you are trying to select/filter instead of changing the elements and uses the appropriate List type instead of Text for the Contains part.

Select duplicated lists from a list of lists (Python 2.7.13)

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]

How to add sequential numbers to a list of tuples

I have a question which looks quite simple, but I could not find an acceptable answer as yet. It looks that variations of it have already been asked here several times, but none of the answers was helpful to me.
Here it is:
I have a lists of tuples, as follows:
reflist = [("Author1", 1900, "Some reference"), ("Author2", 1901, "Another reference"), ("Author3", 1902, "Yet another reference")]
What I want is to add a sequential number to each tuple in the list, so that I got:
reflist = [(1, "Author1", 1900, "Some reference"), (2, "Author2", 1901, "Another reference"), (3, "Author3", 1902, "Yet another reference")]
This looks silly and a list comprehension should do the trick, but I cannot discern just how :-(
Thanks in advance for any assistance you can provide.
enumerate() runs over a sequence and generates index, value pairs. You can't merge directly into your tuples - because tuples are immutable, you can't change their length - but one way you could do it is to convert the tuples you have into lists, make the index number a list, concatenate the two lists together, and convert the result to a tuple:
reflist2 = [tuple([index+1] + list(ref)) for index, ref in enumerate(reflist)]
(I've edited it to index+1 because enumerate starts counting from 0)
f = [tuple(list(elem).insert(0, i)) for elem in reflist for in range(len(reflist))]
What this list comprehension does is that it tells for each original entry in reflist, it should convert it to a list, then insert a number in some integer list to the 0 position of the list, then convert that list back into a tuple, and put it all together in a ne wlist.

If the set.add() function and list serve for the same purpose in Python?

As what mentioned in the Title, if both of them serve for the same purpose?
Most of the time i will chose to use list, and i don't know when is a better time to use set.add() function.
I try both of them and give me the exact same result...
Personally feel list is better. What do you guys think?
a = set()
a.add('a1')
a.add('a2')
a.add('a3')
for ele in a:
print ele
b = []
b.append('a1')
b.append('a2')
b.append('a3')
for ele in b:
print ele
Please advise...
In terms of general data structures, a set structure tends to allow only one element of each value whereas a list may have more than one of each.
In other words, the pseudo-code set.add(7) executed twice results in the set containing the single element 7 (or an error if it considers adding the same element twice to be invalid).
Using a list instead of a set would result in two elements, both being 7.
For Python specifically, adding duplicates to a set is not an error but it still plainly only allows one of each:
>>> s = set()
>>> s.add(1)
>>> s.add(1)
>>> s.add(2)
>>> s
set([1, 2])
The list on the other hand allows multiples:
>>> l = list()
>>> l.append(1)
>>> l.append(1)
>>> l.append(2)
>>> l
[1, 1, 2]
The reason why you didn't see a difference is simply because you added three unique items to the list and set. In that context, they act the same. Behaviour only diverges when you add duplicate items.