0

I need some help with coding a specific logic mentioned below in python 3.6.

Say I have a list 'a'. Note this list is not of static length and the values can vary.

a= ['Theresa', 'Paul', 'lyndsay', 'Nick', 'Tim', 'Ray', 'Charles']

I would like to generate a list like below using these values:

(((((name equals "Theresa") or (name equals "Paul")) or ((name equals "lyndsay") or (name equals "Nick"))) or ((name equals "Tim") or (name equals "Ray"))) or (name equals "Charles"))

The logic for this is that if you notice the brackets, they always compare 2 conditions at a time.

the 1st set below: if you see it compares on 2 values.

((name equals "Theresa") or (name equals "Paul"))

similarly the 2nd set is:

((name equals "lyndsay") or (name equals "Nick"))

now that we have 2 sets, these can be combined and wrapped together with a brackets. This now becomes a single set that can be combined with another set. lets call it set 3

(((name equals "Theresa") or (name equals "Paul")) or ((name equals "lyndsay") or (name equals "Nick")))

moving on, the next set 4 will be:

((name equals "Tim") or (name equals "Ray"))

now set 3 and set 4 can be combined and wrapped together with a brackets. This is set 5:

((((name equals "Theresa") or (name equals "Paul")) or ((name equals "lyndsay") or (name equals "Nick"))) or ((name equals "Tim") or (name equals "Ray")))

Next we have only 1 value remaining, so that becomes our last set:

(name equals "Charles")

This can now be combined with set 5 to get the final string generated from list 'a':

(((((name equals "Theresa") or (name equals "Paul")) or ((name equals "lyndsay") or (name equals "Nick"))) or ((name equals "Tim") or (name equals "Ray"))) or (name equals "Charles"))

Similarly list 'b' should generate:

b= ['key1', 'key2', 'key3', 'key4','key5']

((((keyword equals "key1") or (keyword equals "key2")) or ((keyword equals "key3") or (keyword equals "key4"))) or (keyword equals "key5"))

The 2 from list 'a' and 'b' should be combined using an 'and' operator to give:

((((((name equals "Theresa") or (name equals "Paul")) or ((name equals "lyndsay") or (name equals "Nick"))) or ((name equals "Tim") or (name equals "Ray"))) or (name equals "Charles")) and ((((keyword equals "key1") or (keyword equals "key2")) or ((keyword equals "key3") or (keyword equals "key4"))) or (keyword equals "key5")))

What I have tried so far is I have been able to generate a list using the following code. But don't know how to proceed further:

from math import ceil

size = 2
seq = ['Theresa', 'Paul', 'lyndsay', 'Nick', 'Tim', 'Ray', 'Charles']

split_list = [
    seq[i * size:(i * size) + size]
    for i in range(ceil(len(seq) / size))
]

# print(split_list)
mid_list = []
qs = ""

for i, item in enumerate(split_list):
    sub_q = ""
    if i > 0:
        sub_q = f'{qs} or '

    if len(item) == 2:
        sub_q = f'((name equals "{item[0]}") or (name equals "{item[1]}"))'
    else:
        sub_q = f'(name equals "{item[0]}"))'

    mid_list.append([sub_q])
print(mid_list)

Output: [['((name equals "Theresa") or (name equals "Paul"))'], ['((name equals "lyndsay") or (name equals "Nick"))'], ['((name equals "Tim") or (name equals "Ray"))'], ['(name equals "Charles"))']]

Appreciate any help with this.

Thank you.

2
  • Can you clarify the following points: (1) what is the content of split_list in the line for i, item in enumerate(split_list), (2) is name a variable or just a string? (3) for the code you have provided what does the output look like, when split_list is defined as something? Commented Jan 27, 2021 at 20:59
  • @itprorh66, I have updated the code in the post. Hope this answers your queries. Commented Jan 27, 2021 at 23:19

2 Answers 2

1

I managed to write the following code to generate the string as per my logic.

from math import ceil

size = 2
seq = ['Theresa', 'Paul', 'lyndsay', 'Nick', 'Tim', 'Ray']

odd_length = len(seq) % 2
original_length = len(seq)

split_list = [
    seq[i * size:(i * size) + size]
    for i in range(ceil(len(seq) / size))
]

# print(split_list)
mid_list = []
qs = ""

for i, item in enumerate(split_list):
    sub_q = ""
    if i > 0:
        sub_q = f'{qs} or '

    if len(item) == 2:
        sub_q = f'((name contains "{item[0]}") or (name contains "{item[1]}"))'
    elif original_length == 1:
            sub_q = f'(name contains "{item[0]}")'
    else:
        sub_q = f'(name contains "{item[0]}"))'

    mid_list.append([sub_q])

a = mid_list

while len(mid_list) != 1:
    a = []
    if len(mid_list) > 2:
        q = f'({mid_list[0][0]} or {mid_list[1][0]})'
        a.append([q])
        for i in range(len(mid_list)):
            if i > 1:
                a.append(mid_list[i])
        mid_list = a
    elif len(mid_list) == 2 and odd_length == 1:
        q = f'({mid_list[0][0]} or {mid_list[1][0]}'
        a.append([q])
        for i in range(len(mid_list)):
            if i > 1:
                a.append(mid_list[i])
        mid_list = a
    else:
        q = f'({mid_list[0][0]} or {mid_list[1][0]})'
        a.append([q])
        for i in range(len(mid_list)):
            if i > 1:
                a.append(mid_list[i])
        mid_list = a


print(a[0][0])
Sign up to request clarification or add additional context in comments.

Comments

0

I am not sure if this is what you are looking for, and for the life of me I am not sure I know why you want to create the result, but here is my take: Given:

a= ['Theresa', 'Paul', 'lyndsay', 'Nick', 'Tim', 'Ray', 'Charles']

and the function:

def mergeList(sl):
    rslt = []
    for i in range(1, len(sl), 2):
        rslt.append([f'((name equals {sl[i-1]}) or (name equals {sl[i]}))'])
    if len(sl)%2 == 1:
        rslt.append([f'((name equals {sl[-1]}))'])
    return rslt    

if you execute:

mergeList(a)  

you get:

[['((name equals Theresa) or (name equals Paul))'],
 ['((name equals lyndsay) or (name equals Nick))'],
 ['((name equals Tim) or (name equals Ray))'],
 ['((name equals Charles))']]

6 Comments

Thanks for this. Surely a step closer but still need to group these as per the logic mentioned above. Just a background on why I need this, I have an API for a vendor product and I am trying to code a wrapper to interact with the API. 'name' and 'keyword' are fields in the vendor app. Eventually I end up passing the string generated in the API query string. /restapi/data/?params=(((((name equals "Theresa") or (name equals "Paul")) or ((name equals "lyndsay") or (name equals "Nick"))) or ((name equals "Tim") or (name equals "Ray"))) or (name equals "Charles"))
Can you identify the differences between what you want and my response?
Also, did you want an output which is a string or a list of lists?
Just updated my response to better reflect your changes
The output I need is a string as shown below: (((((name equals "Theresa") or (name equals "Paul")) or ((name equals "lyndsay") or (name equals "Nick"))) or ((name equals "Tim") or (name equals "Ray"))) or (name equals "Charles")) The difference is in the parentheses and how these help group the criteria’s. If you notice the beginning of the o/p, there are 5 parentheses that groups the various sets together. My code is just an intermediary step I was trying.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.