Is there a way, in haskell to merge multiple lists to one list?
e.g.:
Input:
[
[0,2,0,4,0,6,0,1,0,3,0,0,0,0,0],
[0,0,3,0,0,6,0,0,2,0,0,0,0,0,1],
[0,0,0,4,0,0,0,1,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0,3,0,0,0,0,1]
]
Expected Output:
[0,2,3,4,0,6,0,1,2,3,0,0,0,0,1]
You can use transpose (you may need Data.List) to swap lines and columns of your table to simplify the processing.
Example:
[[0, 1, 0, 2, 3],
[0, 0, 2, 0, 3]]
becomes
[[0, 0],
[1, 0],
[0, 2],
[2, 0],
[3, 3]]
Now you have a list of old columns, so you can process them one by one. For example, you could write such a function:
merge list = case dropWhile (== 0) of [] -> 0
(x:_) -> x
Here we drop all leading zeros from the list, and look if the remaining list has some value, then we take it, otherwise we get 0 as a result.
Now we can use this function to process the transposed table like this:
mergeLists lists = map merge (transpose lists)
Now, we can get rid of parentheses:
mergeLists lists = map merge $ transpose lists
Or even get rid of argument (use composition):
mergeLists = map merge . transpose
Here we say, that merging lists is 1) transposing the table and 2) processing each column with merge. Each of these three versions is equivalent, so you can use any of them.
Some further reading on composition: http://learnyouahaskell.com/higher-order-functions#composition
You can see how it works here: https://repl.it/repls/ReasonablePerfectOptimization
EDIT: fixed merge to use pattern matching
Related
I am trying to understand why the index of minus one behaves as it does with the built-in insert function.
# assinging a list to variable a.
a = [1, 2, 3, 4]
print(a) # we get [1, 2, 3, 4]
a.insert(-1, 5)
print(a) # we get [1, 2, 3, 5, 4]
# why is this different than other list indexing using minus one.
It's not, actually. In case you use
>>> a = [1, 2, 3, 4]
>>> a[-1]
4
The [-1] index gives you the last element. All is fine. So why the -1 in insert() function inserts the element before the element, and not as the last? Answer is in the docs:
Insert an item at a given position. The first argument is the index of the element before which to insert, so a.insert(0, x) inserts at the front of the list, and a.insert(len(a), x) is equivalent to a.append(x).
So as you see, it might be counterintuitive, but it's all in the docs. As a sidenote, I'd recommend you reading wtfpython, maybe you'll find some other fancy quirks.
I have this list of tuples:
l1 = [(1, 8), (6, 8), (8, 7), (2, 6)]
I want to compare 1st element of each tuple with 1st element of next tuple
How can I access the next tuple's 1st element?
Since operating lists is a bit easier than tuples, I first made this as list of list as follows:
l1 = [[1, 8], [6, 8], [8, 7], [2, 6]]
and then tried this:
for i in l1:
if l1[i][1] == l1[i+1][1]:
...
but l1[i+1][1] doesn't work
what am I doing wrong in (i+1) code
Try to use range with the length of your list -1 :
for i in range(len(l1) - 1) :
if l1[i][0] == l1[i+1][0]:
...
with this you won't get indexError when reaching your last member of the list.
While comparing adjacent elements when traversing through the elements always make sure your stopping condition is the second last element.
Also if you are comparing the first element your indexing should start at 0 and not 1.
for i in range(len(l1)-1):
if l1[i][0] == l1[i+1][0]:
Good evening,
I have a table in the format of a list of lists. Each list is of the same length. I would like to obtain a smaller list based on the unique values of the numbers (1 list per number whichever shows up first).
tbl = [[1, 'aaa'], [2, 'aab'], [3, 'aac'], [4, 'GGC'], [4, 'GGH'], [6, 'GGS'], [7, 'aad']]
I've tried the following snippet of code:
tbl_simple = [list(x) for x in set(tuple(x) for x in tbl)]
But this line treats the whole list as one big unique value and I end up with the same table. I would like to filter on just the condition of the number (or some column of my choosing). The final result would look like this:
[[1, 'aaa'], [2, 'aab'], [3, 'aac'], [4, 'GGC'], [6, 'GGS'], [7, 'aad']]
Thank you for any assistance.
An easy non-one liner would be:
output = []
seen = set()
for num, letters in tbl:
if num in seen:
continue
output.append([num, letters])
seen.add(num)
Still thinking about a one-liner.
I have two lists and i would like to merge into one list.
def values = [[name:"A",prof:"B"],[exp:["C","E"]]]
def list3=values.flatten(); //flatten is not working
println ("list 2 is"+list3);
Result is same
[[name:A, prof:B], [exp:[C, E]]]
Expected Output:
[[name:A, prof:B, exp:[C, E]]
Flatten will reduce nesting in lists
[[1, 2], [3, 4]].flatten() == [1, 2, 3, 4]
What you have is a non-nested list of maps
Flatten will have no effect
To get the result you're expecting, you want to add all the maps together
You can do this with values.sum()
I am reading Hutton's book, Programming in Haskell.
Here is a function:
pairs :: [a] -> [(a,a)]
pairs xs = zip xs (tail xs)
e.g.
>pairs [1,2,3,4]
>[(1,2),(2,3),(3,4)] --result
Problem is how to read this function ? from left to right?
I am confused how "tail" leave 1 element and then combine it with next element using "zip"
Since "tail" suppose to get all remaining elements from the list right?
I haven't read the book you mentioned, but I'll try to explain what I know.
You're right about the tail function returning everything except the first element of the list. Let's see how zip works,
zip [1, 2, 3, 4] [5, 6, 7, 8]
gives,
[(1, 5), (2, 6), (3, 7), (4, 8)]
Now, consider the output we need from the input we have, observe the transformation required from input to output,
[1, 2, 3, 4] -> [(1,2),(2,3),(3,4)]
From the above application of zip, we can see the output we need can be obtained by calling zip with,
zip [1, 2, 3] [2, 3, 4]
Now, from the docs on zip function, we can see that if the two given lists are of unequal length, the extra items in the longer list are discarded. So, we'd get the same result with,
zip [1, 2, 3, 4] [2, 3, 4]
in which the last 4 in the first input list would be discarded and we get the result we want.
This can be written in a function as,
pairs xs = zip xs (tail xs)
If it is something else you are confused about, do let me know.
zip takes 2 arguments. tail returns its argument with the first element removed, but does not modify its argument.Therefore [1, 2, 3, 4] gets zipped with [2, 3, 4].