List of lists with various lengths and items - change numbers - list

So my problem, to which I have been searching a solution for hours now, is, that I have a list of list with lists of various lengths and different items:
list_1=[[160,137,99,81,78,60],[132,131,131,127,124,123],'none',[99,95,80,78]]
Now I want to change the fifth number of every list and add +1. My problem is, that I keep getting 'out of range' or other problems, because list 3 doesn't contain numbers and list 3+4 don't contain a fifth element.
I have so far found no answer to this. My first guess was adding zeros to the lists, but I'm not supposed to do that. It would also falsify the results, since then it would add +1 to any zero I have created.

Try to fix the previous post, and make minor correction, try it and ask any questions:
Any function should return the modified list, otherwise, you will not get it (unless it's supposed to do in-place changes)
You may try do List Comprehension as well, but that's more involved.
L =[[160,137,99,81,78,60],[132,131,131,127,124,123], None,[99,95,80,78]]
def addOne(L):
for lst in L:
if isinstance(lst, list) and len(lst) >= 5:
lst[4] += 1
return L
print(addOne(L))
Output:
[[160, 137, 99, 81, 79, 60], [132, 131, 131, 127, 125, 123], None, [99, 95, 80, 78]]

Assuming this is in Python,
list_1=[[160,137,99,81,78,60],[132,131,131,127,124,123],'none',[99,95,80,78]]
def addOneToFifthElement(theList):
for list_ in theList:
if type(list_)=="<class 'list'>" and len(list_)>=5:
list_[4] += 1
addOneToFifthElement(list_1)

Related

How do I find the index of the maximum value in the list using Applescript?

I have an int list such as {18, 18, 18, 18, 22, 21}, I want to use Applescript to get the maximum value of this list, and get the maximum index, please teach me
There are two stages to this:
Identifying the maximum value in the list;
Once the maximum value is known, determining the index of the last occurrence of this value in the list.
I'll use a sample list I generated myself in the examples I demonstrate below. However, you can simply substitute your list for mine, and the processes described will work just as well, and produce the results specific to your input.
1. Retrieving the maximum value in a numerical list
A quick-and-dirty way to get the maxium value in the list is to use a bash numeric sort command, and pick the last item:
set L to {4, 24, 78, 32, 1.5, 32, 78, 4, 19, 78}
set text item delimiters to linefeed
do shell script "sort -n <<<" & quoted form of (L as text) & "| tail -n 1"
--> 78
But, in the spirit of problem solving, the computer scientist's approach would be to iterate through the items in the list and perform these operations:
Store the first item's value.
If the next item is of greater value, then replace the currently stored value with the item we just assessed as being greater in value.
If the next item is not of greater value, retain the currently stored value.
Once you reach the end of the list, the stored value must be equal to the greatest value item in the list. At this point, we don't know its position in the list, but we know its value.
Here's the AppleScript that performs this process:
set L to {4, 24, 78, 32, 1.5, 32, 78, 4, 19, 78}
set max to L's first item
repeat with x in L
if x > max then set max to x's contents
end repeat
return max
--> 78
2. Determining the index of a given item in a list
Putting aside the maximum value for now, the second half of the problem involves being able to determine the position of any given item in an ordered list.
The most obvious solution to this is, as before, iterating through each item in the list and performing this operation:
If the current item is equal to the target item, then append its index to the end of a list reserved for storing matching indices.
Once you reach the end of the list, your matched indices list will contain all the positions of the items whose value equal your target item's value; or the matched indices list will be an empty list, indicating that the main list does not contain the value we sought out.
The index of the first item in an AppleScript list is 1. Use the length property of a list to obtain the number of items in the whole list.
Here's a basic AppleScript:
set L to {4, 24, 78, 32, 1.5, 32, 78, 4, 19, 78}
set matches to {}
set target to 78
repeat with i from 1 to L's length
if item i of L = the target then set end of matches to i
end repeat
return the matches
--> {3, 7, 10}
3. The combined process
Combining these two halves of the problem is as simple as running each half in sequence, being mindful to use the result from the first half of the process—the maximum value—as the target value to be sought out in the list:
set L to {4, 24, 78, 32, 1.5, 32, 78, 4, 19, 78}
set max to L's first item
# Get maximum value
repeat with x in L
if x > max then set max to x's contents
end repeat
set matches to {}
set target to max
# Get index of maximum value
repeat with i from 1 to L's length
if item i of L = the target then set end of matches to i
end repeat
return the matches
--> {3, 7, 10}
Finally, as you only want the maximum index, this is simply the last value in the matches list, i.e. 10, which you obtain by replacing return the matches with this line:
return the last item in matches
--> 10
4. Efficiency improvements
Having outlined the basic methods in each process, these aren't necessarily the fastest methods. With lists containing only 10 items, inefficiency is not a noticeable concern. If you had a list of 10,000 items, you would want to be able to reduce the time to get your result.
I think I'm correct in stating that there's no discernible way to speed up the first process in terms of algorithmic improvements: retrieving the maximum value necessitates comparing every item's magnitude and retaining the largest.
Determining the index, however, can be sped up given that we only need to determine the last occurrence of an item in the list.
Therefore, we can run the process as before, but making two changes:
Start from the end of the list instead the beginning.
Stop the process once we find the first match.
Here's the script:
set L to {4, 24, 78, 32, 1.5, 32, 78, 4, 19, 78}
set max to L's first item
# Get maximum value
repeat with x in L
if x > max then set max to x's contents
end repeat
set target to max
# Get index of maximum value
repeat with i from L's length to 1 by -1
if item i of L = the target then exit repeat
end repeat
return i
--> 10
Note here the second repeat loop now runs backwards from the highest index down to 1; and, we no longer require the matches list, so instead we simply exit the loop when a match is found, and see what value of i we were at.
One further improvement to the algorithm here would be to test for the null case to determine whether or not we really need to run through the list at all: the null case is the case where the list doesn't contain the value we seek. AppleScript provides a builtin way to check this:
if the target is not in L then return 0
and this line would sit immediately after set target to max and immediately before repeat with i....
5. Advanced improvements
Another way to improve efficiency, after addressing efficiency of the algorithms themselves, is to address the efficiency of the way the script is written. This is more advanced than you need to concern yourself with now, but here's how I'd probably implement the algorithms if I were writing the script for my own use:
I would define a handler called maximum() that takes a list as its argument and returns the greatest value, and I would implement the scripting of this handler like so:
on maximum(L as list)
local L
if L is {} then return {}
if L's length = 1 then return L's first item
script Array
property x0 : L's first item
property xN : rest of L
property fn : maximum(xN)
property predicate : x0 > fn
end script
tell the Array
if its predicate is true then return its x0
its fn
end tell
end maximum
This uses something called a script object to process the items of the list, which is much, much quicker in AppleScript than conventional iterative repeat loop.
Next, I would define a second handler called lastIndexOf() that takes a supplied value and a list as its two arguments, and returns the highest index at which the supplied value occurs in the given list. My handler would look like this:
on lastIndexOf(x, L as list)
local x, L
if x is not in L then return 0
if L = {} then return
script Array
property x0 : L's last item
property xN : reverse of rest of reverse of L
property predicate : x0 ≠ x
end script
# For the last match only:
if Array's predicate is false then return (Array's xN's length) + 1
# For a match list (comment out line above):
tell the Array
if its predicate is false then ¬
return the lastIndexOf(x, its xN) ¬
& (its xN's length) + 1
return lastIndexOf(x, its xN)
end tell
end lastIndexOf
Then, all I need to do to obtain the result is:
set L to {4, 24, 78, 32, 1.5, 32, 78, 14, 19, 78}
get the lastIndexOf(maximum(L), L)
--> 10
But, don't try and understand what I've done here just yet, and concentrate on understanding the repeat loop algorithms.
I've included these more advanced versions for completeness and for readers who may have wondered, had I left this out, why I didn't provide the most optimal solution I could have.
Whilst the algorithm used in these advanced versions remains the same (it doesn't look like it, but it is), the way the code is written makes these incredibly efficient for large itemed lists.
Note, however, I haven't included any error handling, so if you were to pass those handlers a list that contained non-numerical items, at least one of them would complain.
The maximum value can be determined quite easy with help of AppleScriptObjC and Key-Value Coding
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use framework "Foundation"
set numberList to {18, 18, 18, 18, 22, 21, 22}
set nsNumberList to current application's NSArray's arrayWithArray:numberList
set maxValue to nsNumberList's valueForKeyPath:"#max.intValue") as integer -- 22
If there is only one occurrence of that value of if you want only the index of the first occurrence write
set maxIndex to ((nsNumberList's indexOfObject:maxValue) as integer) + 1 -- AppleScript's lists are 1-based
If there are multiple occurrences of that value and you need all indexes use a loop (unfortunately the efficient native Cocoa API indexesOfObjectsPassingTest: is not available in AppleScriptObjC)
set maxIndexes to {}
repeat with i from 0 to (count numberList) - 1 -- Cocoa's lists are 0-based
if (maxValue's isEqualToNumber:(nsNumberList's objectAtIndex:i)) then
set end of maxIndexes to i + 1
end if
end repeat
maxIndexes -- {5, 7}

Creating an iterator to brute force

Hi so I am trying to write a function hack() that takes no arguments and returns an iterator over all possible passwords.
Basically, I have to user an iterator to brute force a password. All I know from the question is that:
The password consists of three segments.
The first segment of the password is a concatenation of two words in the following list of words: ["hello", "BEGONE", "dog", "MrCool"]
The middle segment is "Donkey20"
And the last segment consists of two digits that together (i.e. 1 and 7 = 17), are no larger than 38. (And at least 0)
My method of thinking is this:
Find all the possible combinations of POSSIBLE_WORDS by using permutations(). (Find all segment 1 possibilities)
For each combination in the new list, add "Donkey20" to the end. (For example: helloBEGONEDonkey20)
Find all possible combinations between the elements in THAT list and POSSIBLE_NUMBERS.
Create an iterator that iterates over all these possible passwords, and return it
My current code only is able to do step 2, but instead of Donkey20 being at the end of each combination it's at the start. (e.g. Donkey20helloBEGONE instead of helloBEGONEDonkey20)
POSSIBLE_WORDS = ["hello", "BEGONE", "dog", "MrCool"]
MIDDLE = "Donkey20"
possible_numbers1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
possible_numbers2 = [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28]
possible_numbers3 = [29, 30, 31, 32, 33, 34, 35, 36, 37, 38]
POSSIBLE_NUMBERS = possible_numbers1 + possible_numbers2 + possible_numbers3
from itertools import permutations, combinations
def hack():
first_words = [''.join(word) for word in permutations(POSSIBLE_WORDS, 2)]
first_words.append(MIDDLE)
first_half = [''.join(word) for word in permutations(first_words, 2)]
Any way to fix this issue? How do I finish the remainder of the steps? Is there a different approach I could use to code this program?
Any help would be very much appreciated!
First of all, there is no reason to build up POSSIBLE_NUMBERS like that. Just use range(39) or list(range(39)) instead.
Your intention in
first_words.append(MIDDLE)
was almost certainly not to tack the single word "Donkey20" onto the end of the list of all possible first parts but was instead to tack it onto the end of each first word. I think that your intention in that part of the code can be better expressed by getting rid of that line as well as the following line and just use the single line
first_half = [word + MIDDLE for word in first_words]
When you are putting together the final possible passwords, you are going to need to turn the numbers into strings. Doubtless you already know about str() but that function has the drawback that str(1) is '1' whereas you probably want '01'. In this context, you might want to use format() since format(1,'02') returns '01'.
This should be enough of a hint to get you going. Since this seems to be homework I don't want to say any more.

Append a list to a list

I have a list of numbers and I want to extract N elements as lists, and store them in another list.
Example:
list1 = [1,2,3,4,5,6,7,8,9]
resultList = [[1,2,3],[4,5,6],[7,8,9]]
I've done the following
def getLines(square, N):
i = 0
line = [None]*N
lines = list()
for elt in square:
line[i] = elt
i += 1
if i == N:
lines.append(line)
i = 0
return lines
Why do I always get the last list three times
[[7,8,9],[7,8,9],[7,8,9]]
when I call the function getLines(list1, 3).
I also tried to eliminate the temporary list and add the elements directly to resultList like this:
def getLines(square, N):
i = 0
j = 0
lines = [[None]*N]*N # Need to be initialized to be able to index it.
for elt in square:
lines[i][j] = elt
j += 1
if j == N:
i += 1
j = 0
return lines
The last group is still appearing N times. Any hints on how to fix that?
This is because you are creating only one inner list object, and altering it.
In pseudocode, what you are doing is:
Create a list called line assigning [None, None, None] to it
Create an empty list called lines
For three times:
-- Pick n items from the square list
-- Assign these three items to line[0], line[1] and line[2]
-- Append line to lines
So, what you are doing is assigning to individual items of line. This is important - you're not making a new object each time, you're changing individual items in the line list.
At the end of it all, line will point to the list [7, 8, 9]. And you can see lines as being substantially [line, line, line] (a list of three times the same object), so specifically now it will point to [[7,8,9], [7,8,9], [7,8,9]].
To solve this, possibly the solution that most keeps your original code is to re-define line after appending it. This way, the variable name line will refer to a different list each time, and you won't have this problem.
def getLines(square, N):
i = 0
line = [None]*N
lines = list()
for elt in square:
line[i] = elt
i += 1
if i == N:
lines.append(line)
line = [None]*N # Now `line` points to a different object
i = 0
return lines
Of course, there is leaner, more Pythonic code that can do the same thing (I see that an answer has already been given).
EDIT - Ok, here goes a somehow more detailed explanation.
Perhaps one of the key concepts is that lists are not containers of other objects; they merely hold references to other objects.
Another key concept is that when you change an item in a list (item assignment), you're not making the whole list object become another object. You're merely changing a reference inside it. This is something we give for granted in a lot of situations, but somehow becomes counter-intuitive when we'd want things to go the other way and "recycle" a list.
As I was writing in the comments, if list was a cat named Fluffy, every time you're appending you're creating a mirror that points to Fluffy. So you can dress Fluffy with a party hat, put a mirror pointing to it, then give Fluffy a clown nose, put on another mirror, then dress Fluffy as a ballerina, add a third mirror, and when you look at the mirrors, all three of them will show the ballerina Fluffy. (Sorry Fluffy).
What I mean is that in practice in your first script, when you do the append:
lines.append(line)
by the first concept I mentioned, you are not making lines contain the current status of line as a separate object. You are appending a reference to the line list.
And when you do,
line[i] = elt
by the second concept, of course line is always the same object; you're just changing what's referenced at the i-th position.
This is why, at the end of your script, lines will appear to "contain three identical objects": because you actually appended three references to the same object. And when you ask to see the content of lists, you will read, three times, the list object in its current status.
In the code I provided above, I re-define the name lists to make it reference a brand new list every time it's been appended to lists:
lines.append(line)
line = [None]*N # Now `line` points to a different object
This way, at the end of the script I have "three different cats" appended, and each one was conveniently named Fluffy just until I had appended it, to give room for a new Fluffy list after that.
Now, in your second script, you do something similar. The key instruction is:
lines = [[None]*N]*N # Need to be initialized to be able to index it.
In this line, you are creating two objects:
- the list [None, None, None]
- the list named lines, which contains N references to the same list [None, None, None].
What you did was just to create straight away Fluffy and the three mirrors pointing at him.
In fact if you change lines[0][2], or lines[1][2], you're just changing the same item [2] of your same Fluffy.
What you actually wanted to do is,
lines = [[None]*N for i in range(N)]
which creates three different cats - I mean, lists, and have lines point to the three.
You might consider solving this like:
def getLines(square, N):
return [square[i:i + N] for i in range(0, len(square), N)]
For example: getLines([1, 2, 3, 4, 5, 6, 7, 8, 9], 3) will return [[1, 2, 3], [4, 5, 6], [7, 8, 9]], or getLines([1, 2, 3, 4, 5, 6, 7, 8, 9], 2) results in [[1, 2], [3, 4], [5, 6], [7, 8], [9]], and so on.

Python - values only being used if they are after the initial in a list

I'm trying to make a program that finds likely friends by finding similarities in user scores in different topics:
def similarity(user,d_list):
user_data=()
user_score=[]
for item in d_list:
if user in item:
user_data=item[1]
if item[0]!=user :
local_score=0
local_score=sum(a*b for a,b in zip(user_data,item[1]))
user_score.append(local_score)
print user_score
return
When using:
ratings=(("mark",[4,8,0,7]),("bob",[3,6,9,1]),("jim",[11,4,6,3]),("steve",[22,19,1,0]))
As the d_list and "mark" as the user, the program works as expected, giving:
[67, 97, 240]
When bob is used, the comparison with mark is set to 0.
[0, 114, 189]
When steve is used the set is just zeros. I'm at a loss.
Got it. The calculation was still nested inside the first iteration through d_list.
def similarity(user,d_list):
user_data=()
user_score=[]
for item in d_list:
if user in item:
user_data=item[1]
for item in d_list:
if item[0]!=user :
local_score=0
local_score=sum(a*b for a,b in zip(user_data,item[1]))
user_score.append(local_score)
print user_score
return

Filters Syntax Explanation

I'm trying to reproduce the filters logic in csharp and was wondering what do the following filters mean?
As a start, I created a parsing tree having LogicalOperator Node, ComparisonOperator Node, Variable Node, Value Node.
The idea is that I could create a tree like this
=
/ \
COST_CENTRE 12456
I'm not sure how to interpret these theorical filters
8*..9*
8?..?12
>A*
>12?A*
Any ideas?
Thank you,
What is the problem Entering Criteria in Filters?
8*..9* result contains all records in which the field has values from (starting with digit 8) to (starting with digit 9), e.g. 8, 88, 838, 9, 91, 9034234 and so on.
8?..?12 result contains all records in which the field has values from (two-digit numbers starting with digit 8) to (three-digit numbers ending with digit 12), e.g. 80, 81, 89, 312, 412, 912 and so on.
>A* result contains all records in which the field has text values that is greater than A*, where A* is any string that starts with "A".
>12?A* result contains all records in which the field has text values that is greater than 12?A*, where 12?A* is any string that starts with "12" then it has any random symbol, then goes "A" and than any number of any symbols.
The most stupid filters I've ever seen!