Select consecutive integers from array in Ruby [closed] - arrays

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
I want to select consecutive integers from an array, for example:
Input: (doesn't have to be sorted)
array = [1, 3, 6, 7, 8, 9, 10, 12, 13, 17]
Expected output:
#=> [6, 7, 8, 9, 10, 12, 13]
This is my code so far:
array = [1, 3, 9, 6, 7, 10, 8, 12, 13, 17]
newarray = []
z = 0
array.sort.each_cons(2) do |x, y|
if y == x + 1
if z == 0
newarray.insert(0, x, y)
else
newarray.push(y)
end
end
z = z + 1
end
newarray #=> [7, 8, 9, 10, 13]
As you can see, 6 and 12 are missing.
What's wrong with my code and - besides the bug - is there a better way to write it?

Your code compares adjacent elements x and y, but pushes x and y only if they are the first elements in the array (if z == 0; newarray.insert(0, x, y)). Otherwise, only y is pushed, so the first element of each group of consecutive integers is missing.
This table illustrates what's going on:
x y y == x+1
--------------------
1 3 false
3 6 false
6 7 true #=> push(7)
7 8 true #=> push(8)
8 9 true #=> push(9)
9 10 true #=> push(10)
10 12 false
12 13 true #=> push(13)
13 17 false
You could fix your code by using z as an indicator for the beginning of a group:
z = true
array.sort.each_cons(2) do |x, y|
if y == x + 1
if z
newarray.push(x, y)
z = false
else
newarray.push(y)
end
else
z = true
end
end
A better way is to use chunk_while that was introduced in Ruby 2.3:
array = [1, 3, 9, 6, 7, 10, 8, 12, 13, 17]
array
.sort #=> [1, 3, 6, 7, 8, 9, 10, 12, 13, 17]
.chunk_while { |x, y| y == x + 1 } #=> [[1], [3], [6, 7, 8, 9, 10], [12, 13], [17]]
.select { |a| a.size > 1 } #=> [[6, 7, 8, 9, 10], [12, 13]]
.flatten #=> [6, 7, 8, 9, 10, 12, 13]
Did you notice that the documentation contains a similar example?
For example, one-by-one increasing subsequence can be chunked as follows:
a = [1,2,4,9,10,11,12,15,16,19,20,21]
b = a.chunk_while {|i, j| i+1 == j }
p b.to_a #=> [[1, 2], [4], [9, 10, 11, 12], [15, 16], [19, 20, 21]]

Related

Eliminating array rows based on a property of consecutive pairs of elements

We are given an array sample a, shown below, and a constant c.
import numpy as np
a = np.array([[1, 3, 1, 11, 9, 14],
[2, 12, 1, 10, 7, 6],
[6, 7, 2, 14, 2, 15],
[14, 8, 1, 3, -7, 2],
[0, -3, 0, 3, -3, 0],
[2, 2, 3, 3, 12, 13],
[3, 14, 4, 12, 1, 4],
[0, 13, 13, 4, 0, 3]])
c = 2
It is convenient, in this problem, to think of each array row as being composed of three pairs, so the 1st row is [1,3, 1,11, 9,14].
DEFINITION: d_min is the minimum difference between the elements of two consecutive pairs.
The PROBLEM: I want to retain rows of array a, where all consecutive pairs have d_min <= c. Otherwise, the rows should be eliminated.
In the 1st array row, the 1st pair (1,3) and the 2nd pair (1,11) have d_min = 1-1=0.
The 2nd pair (1,11) and the 3rd pair(9,14) have d_min = 11-9=2. (in both cases, d_min<=c, so we keep this row in a)
In the 2nd array row, the 1st pair (2,12) and the 2nd pair (1,10) have d_min = 2-1=1.
But, the 2nd pair (1,10) and the 3rd pair(7,6) have d_min = 10-7=3. (3 > c, so this row should be eliminated from array a)
Current efforts: I currently handle this problem with nested for-loops (2 deep).
The outer loop runs through the rows of array a, determining d_min between the first two pairs using:
for r in a
d_min = np.amin(np.abs(np.subtract.outer(r[:2], r[2:4])))
The inner loop uses the same method to determine the d_min between the last two pairs.
Further processing only is done only when d_min<= c for both sets of consecutive pairs.
I'm really hoping there is a way to avoid the for-loops. I eventually need to deal with 8-column arrays, and my current approach would involve 3-deep looping.
In the example, there are 4 row eliminations. The final result should look like:
a = np.array([[1, 3, 1, 11, 9, 14],
[0, -3, 0, 3, -3, 0],
[3, 14, 4, 12, 1, 4],
[0, 13, 13, 4, 0, 3]])
Assume the number of elements in each row is always even:
import numpy as np
a = np.array([[1, 3, 1, 11, 9, 14],
[2, 12, 1, 10, 7, 6],
[6, 7, 2, 14, 2, 15],
[14, 8, 1, 3, -7, 2],
[0, -3, 0, 3, -3, 0],
[2, 2, 3, 3, 12, 13],
[3, 14, 4, 12, 1, 4],
[0, 13, 13, 4, 0, 3]])
c = 2
# separate the array as previous pairs and next pairs
sx, sy = a.shape
prev_shape = sx, (sy - 2) // 2, 1, 2
next_shape = sx, (sy - 2) // 2, 2, 1
prev_pairs = a[:, :-2].reshape(prev_shape)
next_pairs = a[:, 2:].reshape(next_shape)
# subtract which will effectively work as outer subtraction due to numpy broadcasting, and
# calculate the minimum difference for each pair
pair_diff_min = np.abs(prev_pairs - next_pairs).min(axis=(2, 3))
# calculate the filter condition as boolean array
to_keep = pair_diff_min.max(axis=1) <= c
print(a[to_keep])
#[[ 1 3 1 11 9 14]
# [ 0 -3 0 3 -3 0]
# [ 3 14 4 12 1 4]
# [ 0 13 13 4 0 3]]
Demo Link

Merge two ordered arrays into one ordered array

I am writing a method that takes two sorted arrays and I want it to return a merged array with all the values sorted. Given the two arrays below:
array_one = [3, 4, 8]
array_two = [1, 5, 7]
I want my merge_arrays method to return:
[1, 3, 4, 5, 7, 8]
My current algorithm is below:
def merge_arrays(array_one, array_two)
merged_array_size = array_one.length + array_two.length
merged_array = []
current_index_on_one = 0
current_index_on_two = 0
current_merged_index = 0
for i in (0..merged_array_size - 1)
if array_one[current_index_on_one] < array_two[current_index_on_two]
merged_array[current_merged_index] = array_one[current_index_on_one]
current_index_on_one += 1
current_merged_index += 1
else
merged_array[current_merged_index] = array_two[current_index_on_two]
current_index_on_two += 1
current_merged_index += 1
end
end
return merged_array
end
I am getting an error 'undefined method `<' for nil:NilClass'. I don't understand how the conditional is receiving this. I debugged the variables in the conditionals and they are giving true or false values. I'm not sure what is causing this error.
Maybe I am missing the point but you can do:
(array_one + array_two).sort
=> [1, 3, 4, 5, 7, 8]
I am getting an error 'undefined method `<' for nil:NilClass'. I don't understand how the conditional is receiving this.
You start by comparing index 0 to index 0:
[3, 4, 8] [1, 5, 7]
0-----------0 #=> 3 < 1
Then you increment the lower value's index by 1:
[3, 4, 8] [1, 5, 7]
0--------------1 #=> 3 < 5
And so on:
[3, 4, 8] [1, 5, 7]
1-----------1 #=> 4 < 5
[3, 4, 8] [1, 5, 7]
2--------1 #=> 8 < 5
[3, 4, 8] [1, 5, 7]
2-----------2 #=> 8 < 7
At that point you get:
[3, 4, 8] [1, 5, 7]
2--------------3 #=> 8 < nil
Index 3 is outside the array's bounds, so array_two[current_index_on_two] returns nil and:
if array_one[current_index_on_one] < array_two[current_index_on_two]
# ...
end
becomes
if 8 < nil
# ...
end
resulting in ArgumentError(comparison of Integer with nil failed). If nil is on the left hand side, you'd get NoMethodError (undefined method `<' for nil:NilClass).
Here's one way you can write merge using recursion. Note, as you specified, both inputs must already be sorted otherwise the output will be invalid. The inputs can vary in size.
def merge (xs, ys)
if xs.empty?
ys
elsif ys.empty?
xs
else
x, *_xs = xs
y, *_ys = ys
if x < y
[x] + (merge _xs, ys)
else
[y] + (merge xs, _ys)
end
end
end
merge [ 1, 3, 4, 6, 8, 9 ], [ 0, 2, 5, 7 ]
# => [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
Assuming you have two sorted arrays. You need to create pipeline using recursion going to crunch through each array. checking at each iteration to see
which value at index 0 of either array is lower, removing that from the array and appending that value to the result array.
def merge_arrays(a, b)
# build a holder array that is the size of both input arrays O(n) space
result = []
# get lower head value
if a[0] < b[0]
result << a.shift
else
result << b.shift
end
# check to see if either array is empty
if a.length == 0
return result + b
elsif b.length == 0
return result + a
else
return result + merge_arrays(a, b)
end
end
> a = [3, 4, 6, 10, 11, 15]
> b = [1, 5, 8, 12, 14, 19]
> merge_arrays(a, b)
#=> [1, 3, 4, 5, 6, 8, 10, 11, 12, 14, 15, 19]
I made slight changes to your code in order to make it work. See the comments inside.
array_one = [2, 3, 4, 8, 10, 11, 12, 13, 15]
array_two = [1, 5, 6, 7, 9, 14]
def merge_arrays(array_one, array_two)
array_one, array_two = array_two, array_one if array_one.length > array_two.length # (1) swap arrays to make satement (3) work, need array_two always be the longest
merged_array_size = array_one.length + array_two.length
merged_array = []
current_index_on_one = 0
current_index_on_two = 0
current_merged_index = 0
for i in (0...merged_array_size-1) # (2) three points to avoid the error
if (!array_one[current_index_on_one].nil? && array_one[current_index_on_one] < array_two[current_index_on_two]) # (3) check also if array_one is nil
merged_array[current_merged_index] = array_one[current_index_on_one]
current_index_on_one += 1
current_merged_index += 1
else
merged_array[current_merged_index] = array_two[current_index_on_two]
current_index_on_two += 1
current_merged_index += 1
end
end
merged_array[current_merged_index] = array_one[current_index_on_one] || array_two[current_index_on_two] # (4) add the missing element at the end of the loop, looks what happen if you comment out this line
return merged_array
end
p merge_arrays(array_one, array_two)
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
The error was coming because the loop was making one step over. The solution is to stop before and insert the missing element at the end of the loop.
It works also with:
# for i in (1...merged_array_size)
# and
# for i in (1..merged_array_size-1)
# and
# (merged_array_size-1).times do
arr1 = [3, 4, 8, 9, 12]
arr2 = [1, 5, 7, 8, 13]
arr = [arr1, arr2]
idx = [0, 0]
(arr1.size + arr2.size).times.with_object([]) do |_,a|
imin = [0, 1].min_by { |i| arr[i][idx[i]] || Float::INFINITY }
a << arr[imin][idx[imin]]
idx[imin] += 1
end
#=> [1, 3, 4, 5, 7, 8, 8, 9, 12, 13]

iterate over array to find int over 10 and add those two digits together

Trying to iterate over and array and for any digit 10 or higher, split those digits and add them together for instance: 10 > "1" "0" > 1.
I am able to iterate through the array and achieve that. however, it returns nil instead of the digits < 9.
def over_ten_sum
#splits the numbers over 10 into seperate digit and sums them
square_odd.map do |num|
if num > 9
num.to_s.chars.each_slice(2).map { |num_1, num_2| num_1.to_i + num_2.to_i }
end
end
end
With a value of [6, 4, 10, 2, 14, 7, 8, 4, 6, 7, 18, 4] it returns:
=> [nil, nil, [1], nil, [5], nil, nil, nil, nil, nil, [9], nil]
I am trying to have the output be
[6, 4, 1, 2, 5, 7, 8, 6, 7, 9, 4]
Just not seeing the disconnect here. Thank you in advance for any insights.
Suppose you were to write
[1, 2, 3].map { |n| }
#=> [nil, nil, nil]
An array of nils is returned because map returns nil for n if n is not assigned a value in the block. Similarly,
[1, 2, 3].map { |n| 2*n if n > 1 }
#=> [nil, 4, 6]
which is very similar to the problem with the OP's code. If one doesn't want nils in the array returned one simply needs to map each element of the array into a non-nil value:
[1, 2, 3].map { |n| n > 1 ? 2*n : n }
#=> [1, 4, 6]
Now let's look at the line
num.to_s.chars.each_slice(2).map { |num_1, num_2| num_1.to_i + num_2.to_i }
If num = 34, this returns [7], which, except for the fact that 7 is in an array, is correct. On the other hand, if num = 134 the expression returns [4, 4] (i.e., [1+3, 4]), which I don't expect is what is wanted. If, however, the numbers always have two digits, the above expression is the same as:
num[0].to_i + num[1].to_i
which is much simpler.1 To make it more general you need to write something like the following2:
def over_nine_sum(arr)
arr.map { |n| n > 9 ? n.to_s.each_char.reduce(0) { |t,s| t + s.to_i } : n }
end
over_nine_sum [12, 5, 71, 3]
#=> [3, 5, 8, 3]
See Enumerable#reduce (aka inject).
#JörgWMittag noted (see comment) that the sum of the digits of a single-digit number (0-9) is the same as the number itself, so there is no need to treat those numbers differently. We may therefore write
def sum_digits(arr)
arr.map { |n| n.to_s.each_char.reduce(0) { |t,s| t + s.to_i } }
end
sum_digits [12, 5, 71, 3]
#=> [3, 5, 8, 3]
As #steenslag's suggested in a comment, this can be simplified to
def sum_digits(arr)
arr.map { |n| n.digits.sum }
end
which uses the methods Integer#digits and Array#sum (both new in Ruby v2.4).
Consider the steps (for the first version of sum_digits above) when n = 34:
n.to_s.each_char.reduce(0) { |t,s| t + s.to_i }
#=> 34.to_s.each_char.reduce(0) { |t,s| t + s.to_i }
#=> "34".each_char.reduce(0) { |t,s| t + s.to_i }
Now reduce initializes the block variable t (the "memo", which is returned) to zero and passes the first digit of "34" to the block and assigns it to the block variable s:
t = 0
s = "3"
The block calculation is:
t + s.to_i
#=> 0 + "3".to_i
#=> 3
which is the updated value of t. Next,
s = "4"
t + s.to_i
#=> 3 + "4".to_i
#=> 3 + 4
#=> 7
1. Another problem is that if square_odd is a local variable, Ruby will raise an "undefined variable or method" exception when it evaluates it.
2. n.to_s.each_char.reduce(0)... is preferable to n.to_s.chars.reduce(0)... because chars returns a temporary array whereas each_char returns an enumerator.
Remove the if:
def over_ten_sum
#splits the numbers over 10 into seperate digit and sums them
square_odd.map do |num|
num.to_s.chars.each_slice(2).map { |num_1, num_2| num_1.to_i + num_2.to_i }
end.flatten
end
#=> [6, 4, 1, 2, 5, 7, 8, 4, 6, 7, 9, 4]
What was wrong? if num > 9 left out every other number from being treated and nothing was returned, so you got nil each time. To make it clearer, check the following code:
def over_ten_sum
#splits the numbers over 10 into seperate digit and sums them
square_odd.map do |num|
if num > 9
num.to_s.chars.each_slice(2).map { |num_1, num_2| num_1.to_i + num_2.to_i }
else
num
end
end.flatten
end
#=> [6, 4, 1, 2, 5, 7, 8, 4, 6, 7, 9, 4]
As you can see, the result is the same, because else send num back as it is when it is not greater than 9.

How do I split a 9x9 array into 9 3x3 components

I have a 9x9 multidimensional array that represents a sudoku game. I need to break it into it's 9 3x3 many components. How would this be done? I have absolutely no idea where to begin, here.
game = [
[1, 3, 2, 5, 7, 9, 4, 6, 8],
[4, 9, 8, 2, 6, 1, 3, 7, 5],
[7, 5, 6, 3, 8, 4, 2, 1, 9],
[6, 4, 3, 1, 5, 8, 7, 9, 2],
[5, 2, 1, 7, 9, 3, 8, 4, 6],
[9, 8, 7, 4, 2, 6, 5, 3, 1],
[2, 1, 4, 9, 3, 5, 6, 8, 7],
[3, 6, 5, 8, 1, 7, 9, 2, 4],
[8, 7, 9, 6, 4, 2, 1, 5, 3]
]
Split into chunks, it becomes
chunk_1 = [
[1, 3, 2],
[4, 9, 8],
[7, 5, 6]
]
chunk_2 = [
[5, 7, 9],
[2, 6, 1],
[3, 8, 4]
]
...and so on
That was a fun exercise!
Answer
game.each_slice(3).map{|stripe| stripe.transpose.each_slice(3).map{|chunk| chunk.transpose}}.flatten(1)
It would be cumbersome and not needed to define every chunk_1, chunk_2, ....
If you want chunk_2, you can use extract_chunks(game)[1]
It outputs [chunk_1, chunk_2, chunk_3, ..., chunk_9], so it's an Array of Arrays of Arrays :
1 3 2
4 9 8
7 5 6
5 7 9
2 6 1
3 8 4
4 6 8
3 7 5
2 1 9
6 4 3
5 2 1
...
You can define a method to check if this grid is valid (it is) :
def extract_chunks(game)
game.each_slice(3).map{|stripe| stripe.transpose.each_slice(3).map{|chunk| chunk.transpose}}.flatten(1)
end
class Array # NOTE: Use refinements if you don't want to patch Array
def has_nine_unique_elements?
self.flatten(1).uniq.size == 9
end
end
def valid?(game)
game.has_nine_unique_elements? &&
game.all?{|row| row.has_nine_unique_elements? } &&
game.all?{|column| column.has_nine_unique_elements? } &&
extract_chunks(game).all?{|chunk| chunk.has_nine_unique_elements? }
end
puts valid?(game) #=> true
Theory
The big grid can be sliced in 3 stripes, each containing 3 rows of 9 cells.
The first stripe will contain chunk_1, chunk_2 and chunk_3.
We need to cut the strip vertically into 3 chunks. To do so :
We transpose the strip,
Cut it horizontally with each_slice,
transpose back again.
We do the same for stripes #2 and #3.
To avoid returning an Array of Stripes of Chunks of Rows of Cells, we use flatten(1) to remove one level and return an Array of Chunks of Rows of Cells. :)
The method Matrix#minor is tailor-made for this:
require 'matrix'
def sub3x3(game, i, j)
Matrix[*game].minor(3*i, 3, 3*j, 3).to_a
end
chunk1 = sub3x3(game, 0, 0)
#=> [[1, 3, 2], [4, 9, 8], [7, 5, 6]]
chunk2 = sub3x3(game, 0, 1)
#=> [[5, 7, 9], [2, 6, 1], [3, 8, 4]]
chunk3 = sub3x3(game, 0, 2)
#=> [[4, 6, 8], [3, 7, 5], [2, 1, 9]]
chunk4 = sub3x3(game, 1, 0)
#=> [[6, 4, 3], [5, 2, 1], [9, 8, 7]]
...
chunk9 = sub3x3(game, 2, 2)
#=> [[6, 8, 7], [9, 2, 4], [1, 5, 3]]
Ruby has not concept of "rows" and "columns" of arrays. For convenience, therefore, I will refer to the 3x3 "subarray" of game, at offsets i and j (i = 0,1,2, j = 0,1,2), as the 3x3 submatrix of m = Matrix[*game] whose upper left value is at row offset 3*i and column offset 3*j of m, converted to an array.
This is relatively inefficient as a new matrix is created for the calculation of each "chunk". Considering the size of the array, this is not a problem, but rather than making that more efficient you really need to rethink the overall design. Creating nine local variables (rather than, say, an array of nine arrays) is not the way to go.
Here's a suggestion for checking the validity of game (that uses the method sub3x3 above) once all the open cells have been filled. Note that I've used the Wiki description of the game, in which the only valid entries are the digits 1-9, and I have assumed the code enforces that requirement when players enter values into cells.
def invalid_vector_index(game)
game.index { |vector| vector.uniq.size < 9 }
end
def sub3x3_invalid?(game, i, j)
sub3x3(game, i, j).flatten.uniq.size < 9
end
def valid?(game)
i = invalid_vector_index(game)
return [:ROW_ERR, i] if i
j = invalid_vector_index(game.transpose)
return [:COL_ERR, j] if j
m = Matrix[*game]
(0..2).each do |i|
(0..2).each do |j|
return [:SUB_ERR, i, j] if sub3x3_invalid?(game, i, j)
end
end
true
end
valid?(game)
#=> true
Notice this either returns true, meaning game is valid, or an array that both signifies that the solution is not valid and contains information that can be used to inform the player of the reason.
Now try
game[5], game[6] = game[6], game[5]
so
game
#=> [[1, 3, 2, 5, 7, 9, 4, 6, 8],
# [4, 9, 8, 2, 6, 1, 3, 7, 5],
# [7, 5, 6, 3, 8, 4, 2, 1, 9],
# [6, 4, 3, 1, 5, 8, 7, 9, 2],
# [5, 2, 1, 7, 9, 3, 8, 4, 6],
# [2, 1, 4, 9, 3, 5, 6, 8, 7],
# [9, 8, 7, 4, 2, 6, 5, 3, 1],
# [3, 6, 5, 8, 1, 7, 9, 2, 4],
# [8, 7, 9, 6, 4, 2, 1, 5, 3]]
valid?(game)
#=> [:SUB_ERR, 1, 0]
The rows and columns are obviously still valid, but this return value indicates that at least one 3x3 subarray is invalid and the array
[[6, 4, 3],
[5, 2, 1],
[2, 1, 4]]
was the first found to be invalid.
You could create a method that generates a single 3X3 chunk from a given index. since the sudoku board is of length 9, that will produce 9 3X3 chunks for you. see below.
#steps
#you'll loop through each index of the board
#to get the x value
#you divide the index by 3 and multiply by 3
#to get the y value
#you divide the index by 3, take remainder and multiply by 3
#for each x value, you can get 3 y values
#this will give you a single 3X3 box from one index so
def three_by3(index, sudoku)
#to get x value
x=(index/3)*3
#to get y value
y=(index%3)*3
(x...x+3).each_with_object([]) do |x,arr|
(y...y+3).each do |y|
arr<<sudoku[x][y]
end
end
end
sudoku = [ [1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2],
[1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2],
[1,2,3,4,5,6,7,8,9],
[2,3,4,5,6,7,8,9,1],
[3,4,5,6,7,8,9,1,2]]
p (0...sudoku.length).map {|i| three_by3(i,sudoku)}
#output:
#[[1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2],
# [1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2],
# [1, 2, 3, 2, 3, 4, 3, 4, 5],
# [4, 5, 6, 5, 6, 7, 6, 7, 8],
# [7, 8, 9, 8, 9, 1, 9, 1, 2]]

How to select a portion of a NumPy array efficiently?

I'm switching from Matlab/octve to Numpy/Scipy.
To select a segment of a Matlab array, it was quite easy.
e.g.
>> x = [1, 2, 3, 4; 5, 6, 7, 8; 9, 10, 11, 12]
x =
1 2 3 4
5 6 7 8
9 10 11 12
>> y = x(2:3, 1:2)
y =
5 6
9 10
How can the same thing be done with NumPy when
x = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
As Indexing > Other indexing options in the NumPy documentation mentions,
The slicing and striding works exactly the same way it does for lists and tuples except that they can be applied to multiple dimensions as well.
For your example, this means
import numpy as np
x = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
# array([[ 1, 2, 3, 4],
# [ 5, 6, 7, 8],
# [ 9, 10, 11, 12]])
x[1:3, 0:2]
# => array([[ 5, 6],
# [ 9, 10]])
Most notable difference to Matlab is probably that indexing is zero-based (i.e., first element has index 0) and that index ranges (called 'slices' in Python) are expressed with an exclusive upper bound: l[4:7] gets l[4], l[5] and l[6] (the 3rd to the 7th element), but not l[7] (the 8th element).
The Python tutorial's section on lists will give you a feeling for how indexing and slicing works for normal (1-dimensional) collections.

Resources