Groovy: Add some element of list to another list - groovy

list1 = [[1,'Rob','Ben', 'Ni', 'cool'],[2,'Jack','Jo','Raj','Giri'],[...]....]
list2 = [['20 May 2013',20],['25 May 2013',26],[...]....]
there will be 100 of such records
i want the resulting list like
list1 = [[1, '20 May 2013', 20, 'Rob','Ben','Ni', 'cool'],[2,'25 May 2013', 26, 'Jack','Jo','Raj','Giri']]
any suggestion ?

[list1, list2].transpose()*.flatten()
Assuming cardinality of list1 and list2 is same.
UPDATE
Question is modified drastically now, but you can get what you seek by extending the transpose as below:
[list1, list2].transpose()*.flatten()
.collect{[it[0], it[-2..-1], it[1..-3]]}*.flatten()

How about this?
def i = 0
def combined = list1.collect([]) { it + list2[i++] }

The result row isn't the concatenation of the two list rows - it takes the second row and inserts it into index 1 of the first row, without the last two elements. So
[list1, list2].transpose()*.flatten()
won't work - tho' it is pretty cool :-). However,
[list1,list2].transpose().collect { def l = it.flatten(); l[0..0] + l[5..6] + l[1..2] }
gives the result show in the question. And I fully admit to standing on the backs of giants :-)

Related

How to create a list of named lists in Python?

I need to create a list of named lists, so that I can iterate over them. This works, but I'm wondering if there isn't a better way.
terms = []; usedfors = []; broaders = []; narrowers = []
termlist = [terms, usedfors, broaders, narrowers]
The reason for doing it this way is that I have a function do_some_list_operation(l) and I want to do something like
for i in termlist:
do_some_list_operation(i)
rather than
do_some_list_operation(terms)
do_some_list_operation(usedfors)
do_some_list_operation(broaders)
do_some_list_operation(narrowers)
I've been searching for 'how to build list of named lists' to no avail.
The way you are doing it is fine but be aware that you are creating a list of lists when you defined termlist. If you want to have the name of the lists then termlist should be:
termlist = ["terms","usedfors", "broaders", "narrowers"]
Now if you want to use these strings as list names you can use globals() or locals() e.g.:
terms = [1]; usedfors = [2]; broaders = [3,4,8]; narrowers = [5]
termlist = ["terms","usedfors", "broaders", "narrowers"]
for i in termlist:
print(sum(locals()[i]))
output:
1
2
15
5
While I like the answer by #jayvee and upvoted it, I think a more conventional answer would be one based on using a dictionary as first suggested by #msaw328.
Starting with our new data structure:
term_data = {
"terms": [1],
"usedfors": [2],
"broaders": [3, 4, 5],
"narrowers": [6, 7]
}
Perhaps like:
for term in term_data:
print(f"{term} sums to {sum(term_data[term])}")
or even
for term, term_value in term_data.items():
print(f"{term} sums to {sum(term_value)}")
Both should give you:
terms sums to 1
usedfors sums to 2
broaders sums to 12
narrowers sums to 13

How to subtract adjacent items in list with unknown length (python)?

Provided with a list of lists. Here's an example myList =[[70,83,90],[19,25,30]], return a list of lists which contains the difference between the elements. An example of the result would be[[13,7],[6,5]]. The absolute value of (70-83), (83-90), (19-25), and (25-30) is what is returned. I'm not sure how to iterate through the list to subtract adjacent elements without already knowing the length of the list. So far I have just separated the list of lists into two separate lists.
list_one = myList[0]
list_two = myList[1]
Please let me know what you would recommend, thank you!
A custom generator can return two adjacent items at a time from a sequence without knowing the length:
def two(sequence):
i = iter(sequence)
a = next(i)
for b in i:
yield a,b
a = b
original = [[70,83,90],[19,25,30]]
result = [[abs(a-b) for a,b in two(sequence)]
for sequence in original]
print(result)
[[13, 7], [6, 5]]
Well, for each list, you can simply get its number of elements like this:
res = []
for my_list in list_of_lists:
res.append([])
for i in range(len(my_list) - 1):
# Do some stuff
You can then add the results you want to res[-1].

List index out of range with one some data sets?

I am trying to code up a numerical clustering tool. Basically, I have a list (here called 'product') that should be transformed from an ascending list to a list that indicates linkage between numbers in the data set. Reading in the data set, removing carriage returns and hyphens works okay, but manipulating the list based on the data set is giving me a problem.
# opening file and returning raw data
file = input('Data file: ')
with open(file) as t:
nums = t.readlines()
t.close()
print(f'Raw data: {nums}')
# counting pairs in raw data
count = 0
for i in nums:
count += 1
print(f'Count of number pairs: {count}')
# removing carriage returns and hyphens
one = []
for i in nums:
one.append(i.rsplit())
new = []
for i in one:
for a in i:
new.append(a.split('-'))
print(f'Data sets: {new}')
# finding the range of the final list
my_list = []
for i in new:
for e in i:
my_list.append(int(e))
ran = max(my_list) + 1
print(f'Range of final list: {ran}')
# setting up the product list
rcount = count-1
product = list(range(ran))
print(f'Unchanged product: {product}')
for i in product:
for e in range(rcount):
if product[int(new[e][0])] < product[int(new[e][1])]:
product[int(new[e][1])] = product[int(new[e][0])]
else:
product[int(new[e][0])] = product[int(new[e][1])]
print(f'Resulting product: {product}')
I expect the result to be [0, 1, 1, 1, 1, 5, 5, 7, 7, 9, 1, 5, 5], but am met with a 'list index out of range' when using a different data set.
the data set used to give the above desired product is as follows: '1-2\n', '2-3\n', '3-4\n', '5-6\n', '7-8\n', '2-10\n', '11-12\n', '5-12\n', '\n'
However, the biggest issue I am facing is using other data sets. If there is not an additional carriage return, as it turns out, I will have the list index out of range error.
I can't quite figure out what you're actually trying to do here. What does "indicates linkages" mean, and how does the final output do so? Also, can you show an example of a dataset where it actually fails? And provide the actual exception that you get?
Regardless, your code is massively over-complicated, and cleaning it up a little may also fix your index issue. Using nums as from your sample above:
# Drop empty elements, split on hyphen, and convert to integers
pairs = [list(map(int, item.split('-'))) for item in nums if item.strip()]
# You don't need a for loop to count a list
count = len(pairs)
# You can get the maximum element with a nested generator expression
largest = max(item for p in pairs for item in p)
Also, in your final loop you're iterating over product while also modifying it in-place, which tends to not be a good idea. If I had more understanding of what you're trying to achieve I might be able to suggest a better approach.

Editing the elements of a list in python 3

My question is kind of a two part question.
If you are given a list
numbers = [10, 20, 30, 100]
and you wish to edit every element inside the list by adding 10 to each element. How would I go about doing this? And are you able to do this without creating a separate list?
Similarly, if you are given a list such as:
words = ['hello', 'hey', 'hi']
and wish to change every letter h inside the list to another letter say 'r' would it be a similar algorithm as the last?
Because you said you don't want to create a new list, you can't use list comprehension or map function as #gcandal suggested. You can try this instead.
def update_list(l, fn):
for i in range(len(l)):
l[i] = fn(l[i])
update_list(numbers, lambda a: a + 10)
update_list(words, lambda s: s.replace('h', 'r'))
You can do it by applying map:
numbers_plus_ten = map(lambda number: number + 10, numbers)
Or using list comprehension:
numbers_plus_ten = [number + 10 for number in numbers]

Common values in a Python dictionary

I'm trying to write a code that will return common values from a dictionary based on a list of words.
Example:
inp = ['here','now']
dict = {'here':{1,2,3}, 'now':{2,3}, 'stop':{1, 3}}
for val in inp.intersection(D):
lst = D[val]
print(sorted(lst))
output: [2, 3]
The input inp may contain any one or all of the above words, and I want to know what values they have in common. I just cannot seem to figure out how to do that. Please, any help would be appreciated.
The easiest way to do this is to just count them all, and then make a dict of the values that are equal to the number of sets you intersected.
To accomplish the first part, we do something like this:
answer = {}
for word in inp:
for itm in word:
if itm in answer:
answer[itm] += 1
else:
answer[itm] = 1
To accomplish the second part, we just have to iterate over answer and build an array like so:
answerArr = []
for i in answer:
if (answer[i] == len(inp)):
answerArr.append(i)
i'm not certain that i understood your question perfectly but i think this is what you meant albeit in a very simple way:
inp = ['here','now']
dict = {'here':{1,2,3}, 'now':{2,3}, 'stop':{1, 3}}
output = []
for item in inp:
output.append(dict[item])
for item in output:
occurances = output.count(item)
if occurances <= 1:
output.remove(item)
print(output)
This should output the items from the dict which occurs in more than one input. If you want it to be common for all of the inputs just change the <= 1 to be the number of inputs given.

Resources