Extract consecutive numbers to form ranges in scala list - list

i have a scala list of tuples,
val stdLis:List[(String,Int)]=null
I need to combine the consecutive integers in the list to form ranges. The final result only needs ranges of integers from the list. The following approach leaves the non-consecutive numbers. But i need to form ranges for the consecutive numbers and also retain non consecutive numbers in the final list.
def mergeConsecutiveNum(lis:List[(String,Int)])={
var lisBuf = new ListBuffer[(String,Int)]
val newRanges = new ListBuffer[(Int,Int)]()
if(lis.size>1)
lis.sliding(2).foreach{i=>
if(i(0)._2+1 == i(1)._2)
lisBuf.appendAll(i)
else{
//println(lisBuf)
if(lisBuf.size>1) {
newRanges.append((lisBuf.head._2, lisBuf.last._2))
newRanges.append((i(0)._2,i(1)._2))
}
lisBuf.clear()
}
}else
newRanges.append((lis.head._2,0))
newRanges
}
for example:
val lis = List(("a",1),("b",2),("c",3),("d",4),("e",6),("f",7),("g",9))
it should give
lis((1,4),(6,7),(9,0))

Don't exactly know what you are asking.
Your code does not return anything.
Anyways, assuming that you need to merge two consecutive numbers in the list and create a range of list based on those numbers, here is something you can try
List(("", 5),("", 10),("", 6),("", 10)).map(_._2).grouped(2).map(ele => ele(0) to ele(1)).toList
List(Range(5, 6, 7, 8, 9, 10), Range(6, 7, 8, 9, 10))

Related

How to display interaction element with order way of list one in Kotlin

I have two lists and I want to return a result in the following way:
the result should contain elements that are in list one and list two
output should be same order as per first list
Input :
val first = listOf(1, 2, 3, 4, 5,7,9,15,11)
val second = listOf(2, 15 , 4,3, 11)
Output:
val output = listOf(2,3,4,15,11)
Please help me to learn how to get common values in both lists in order of list first in Kotlin.
You can do
val output = first.filter { second.contains(it) }
What you are looking for is the intersection of the two lists:
val output = first.intersect(second)
As pointed out by #Ivo the result is a Set which can be turned into a list with output.toList(). However, since the result is a set, it contains no duplicates, e.g. if first is listOf(1,2,3,1,2,3) and second is listOf(2,4,2,4), the result will be equal to setOf(2).
If this is not acceptable, the solution of #Ivo should be used instead.

Python: referring to each duplicate item in a list by unique index

I am trying to extract particular lines from txt output file. The lines I am interested in are few lines above and few below the key_string that I am using to search through the results. The key string is the same for each results.
fi = open('Inputfile.txt')
fo = open('Outputfile.txt', 'a')
lines = fi.readlines()
filtered_list=[]
for item in lines:
if item.startswith("key string"):
filtered_list.append(lines[lines.index(item)-2])
filtered_list.append(lines[lines.index(item)+6])
filtered_list.append(lines[lines.index(item)+10])
filtered_list.append(lines[lines.index(item)+11])
fo.writelines(filtered_list)
fi.close()
fo.close()
The output file contains the right lines for the first record, but multiplied for every record available. How can I update the indexing so it can read every individual record? I've tried to find the solution but as a novice programmer I was struggling to use enumerate() function or collections package.
First of all, it would probably help if you said what exactly goes wrong with your code (a stack trace, it doesn't work at all, etc). Anyway, here's some thoughts. You can try to divide your problem into subproblems to make it easier to work with. In this case, let's separate finding the relevant lines from collecting them.
First, let's find the indexes of all the relevant lines.
key = "key string"
relevant = []
for i, item in enumerate(lines):
if item.startswith(key):
relevant.append(item)
enumerate is actually quite simple. It takes a list, and returns a sequence of (index, item) pairs. So, enumerate(['a', 'b', 'c']) returns [(0, 'a'), (1, 'b'), (2, 'c')].
What I had written above can be achieved with a list comprehension:
relevant = [i for (i, item) in enumerate(lines) if item.startswith(key)]
So, we have the indexes of the relevant lines. Now, let's collected them. You are interested in the line 2 lines before it and 6 and 10 and 11 lines after it. If your first lines contains the key, then you have a problem – you don't really want lines[-1] – that's the last item! Also, you need to handle the situation in which your offset would take you past the end of the list: otherwise Python will raise an IndexError.
out = []
for r in relevant:
for offset in -2, 6, 10, 11:
index = r + offset
if 0 < index < len(lines):
out.append(lines[index])
You could also catch the IndexError, but that won't save us much typing, as we have to handle negative indexes anyway.
The whole program would look like this:
key = "key string"
with open('Inputfile.txt') as fi:
lines = fi.readlines()
relevant = [i for (i, item) in enumerate(lines) if item.startswith(key)]
out = []
for r in relevant:
for offset in -2, 6, 10, 11:
index = r + offset
if 0 < index < len(lines):
out.append(lines[index])
with open('Outputfile.txt', 'a') as fi:
fi.writelines(out)
To get rid of duplicates you can cast list to set; example:
x=['a','b','a']
y=set(x)
print(y)
will result in:
['a','b']

Search for item in a list of tuples

I have a list of tuples structured as per the below (data is example only):
[('aaa', 10), ('bbb', 10), ('ccc', 12), ('ddd', 12), ('eee', 14)]
I need to search the second item in each of the tuples (the number) to see if it exists in the list (eg search for 12 = found, search for 5 = not found.
Currently I am using the below, which works but may not be the best way in Python:
not_there = True
for a in final_set:
if final_set[1] == episode_id:
not_there = False
break
What is the best / most efficient way in Python to do this?
Maybe you can try something like this :
test = [('aaa', 10), ('bbb', 10), ('ccc', 12), ('ddd', 12), ('eee', 14)]
number = 10
for i in test:
if number in i:
print("Number {} found.".format(number))
else:
print("Number {} not found".format(number))
That should work regardless you're searching element 1 in the tuple (the 'aaa') or element 2 (the number).
Hope this helps.
What about this:
is_there = (len([item for item in final_set if item[1] == episode_id]) > 0)
Basically, [item for item in final_set if item[1] == episode_id] is a list comprehension expression which creates a list of the items in final_set such that item[1] == episode_id.
Then, you can check the length of the resulting list: if it is greater than 0, than something has been found.

ValueError:[number] is not in the list, even though it is and the code i believe is correct

When i execute this testing code below, i get the error below it:
my_numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
my_input = input("Pick a number from 1 to 10?")
number_index = my_numbers.index(my_input)
print(number_index)
ERROR-----
number_index = my_numbers.index(my_input) ValueError: '1' is not in
list
is this python? if so, look like is python 3, then the error is simple: input give you a string, and you have a list of integers and no integer is going to be equal to a string, ever, so when you pass my_input, a string, to index it search in the list my_numbers for a match but all the things inside it are integer so it fail and give the error. The solution is simple transform the input to a integer like this:
my_input = int( input("Pick a number from 1 to 10?") )
the same apply to other languages but the fine details may vary...

Compact way to write a list of lists

I am writing a program that outputs a list of ordered lists of numbers. Say the output is as follows:
[1,1,1];
[1,1,2]
I would like to look at the output by eye and make some sense of it, but my output is hundreds to thousands of lines long. I would like to write the output in the following more compact format: [1,1,1/2], where the slash indicates that in the third slot I can have a 1 or a 2. So, for a longer example, [1/2, 1/3, 5, 8/9] would be the compact way of writing [1,1,5,8];[1,1,5,9];[1,3,5,8]; etc. Can anyone suggest a pseudocode algorithm for accomplishing this?
Edit: All of the lists are the same length. Also, I expect in general to have multiple lists at the end. For example {[1,1,2], [1,1,3], [1,2,4]} should become {[1,1,2/3], [1,2,4]}.
What'd I do is use a hash at each element in the first list. You'd then iterate through the remaining lists, and for each position in the other lists, you'd check against the hash in the first / original list for that index to see if you'd seen it before. So you'd end up with something like:
[1 : {1}, 1: {1, 3}, 5: {5}, 8: {8, 9}]
And then when printing / formatting the list, you'd just print each key in the hash, except you'd use slashes or whatever.
EDIT: Bad Psuedocode (python)(untested):
def shorten_list(list_of_lists):
primary_list = list_of_lists[0]
hash_values = [{} * len(primary_list)]
for i in range(len(list_of_lists)):
current_list = list_of_lists[i]
for j in range(current_list):
num = current_list[j]
if num not in hash_values[j]:
hash_values[j] = j
for i in range(len(hash_values)):
current_dict = hash_values[i]
print primary_list[i]
for key in current_dict:
if key != primary_list[i]:
print '/', key
Here's actual code to sort the lists the way you wanted. But maybe the most useful visualization would be a scatter plot. Import the data into your favorite spreadsheet, and plot away.
$(document).ready( function(){
var numbers = [
[1, 1, 5, 8],
[1, 1, 5, 9],
[1, 3, 5],
[1, 1, 5, 10, 15]];
$('#output').text(JSON.stringify(compactNumbers(numbers)));
});
function compactNumbers(numberlists){
var output = [];
for(var i = 0; i < numberlists.length; i++){
for(var j = 0; j < numberlists[i].length; j++) {
if(!output[j]) output[j] = [];
if($.inArray(numberlists[i][j], output[j]) == -1){
output[j].push(numberlists[i][j]);
}
}
}
return(output);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="output"></div>