Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there any way to loop the second list multiple times to properly riffle two lists in Python similar to the Mathematica function?

I’m trying to convert the Mathematica built-in function, "Riffle" into python. Right now, my main focus is getting it to riffle two lists properly (I will worry about adding values at certain indexes later). The Mathematica function is tricky, its results are very dependent on the lengths of the lists. So far, I have created something that works the same as Mathematica for every case, except when the difference in the length of the lists is greater than the length of the second list. Mathematica handles this by iterating over the second list over and over again, until the first list has been exhausted. This is the issue I am having, I can’t seem to write something that does this successfully.

The main issue is within the second case where len1>len2. Any help would be much appreciated.

Here is my code:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

def riffle(vec1, vec2):
    '''
    This function combines two lists into one new list in which every other value
    of the resulting list is a value from the first list, separated by a value
    from the second list. If the first list is larger, the second list will loop
    over itself more than once. If the lists are not the same size, the last value is
    removed from the result list. If they are the same size, each value from each 
    list will be added.

    Inputs:
        vec1: The first vector (list). The length of this vector determines how
        the riffling will occur. ie: riffle(vec1,vec2) != riffle(vec2, vec1) if 
        the vectors are not the same length.

        vec2: the second vector (list) which will be riffled into vec1.

    Output:
        result: a list containing the riffled vectors.

    Example:
    vector1 = [1, 2, 3]
    vector2 = ['a', 'b', 'c', 'd']
    result = [1, 'a', 2, 'b', 3]

    vector1 = [1, 2, 3, 4]
    vector2 = ['a', 'b', 'c', 'd']
    result = [1, 'a', 2, 'b', 3, 'c', 4, 'd']

    vector1 = [1, 2, 3, 4, 5, 6]
    vector2 = ['a', 'b', 'c', 'd']
    result = [1, 'a', 2, 'b', 3, 'c', 4, 'a', 5, 'b', 6]
    '''
    result = []
    len1 = len(vec1)
    len2 = len(vec2)
    min_len = min(len1, len2)
    n = len1 -len2 
    m = n - len2

    if len1 == len2:
        for i in range(min_len):
            result.append(vec1[i])
            result.append(vec2[i])

    if len1 > len2:
        for i in range(min_len):
            if vec2[i] == vec2[-1]:
                if n < len2:
                    for j in range(n+1):
                        result.append(vec1[i+j])
                        result.append(vec2[j])
                else: 
                    for j in range(n+1):
                        if j == vec2[-1]:
                            for k in range(n):
                                result.append(vec1[i+k])
                                result.append(vec2[k])
                        else: 
                            result.append(vec1[i+j])
                            result.append(vec2[j])

            else:
                result.append(vec1[i])
                result.append(vec2[i])
        result.pop(-1)


    if len2 > len1:
        for i in range(min_len):
            result.append(vec1[i])
            result.append(vec2[i])
        result.pop(-1)

    return result

My main struggle is within the case where n is not less than len2. I don’t know how to make python iterate over the second list more than once until the first list is exhausted. However, if someone knows a better method that accomplishes the same thing as Mathematica’s Riffle function in Python, please let me know.

>Solution :

Use itertools.cycle() to keep repeating vec2 as needed. Then use zip() to loop over the two lists in parallel.

from itertools import cycle

def riffle(vec1, vec2):
    result = []
    for x, y in zip(vec1, cycle(vec2)):
        result.append(x)
        result.append(y)

    if len(vec2) > len(vec1):
        result.pop() # remove last element

    return result
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading