Invalid multipolygon of valid individual polygons

Could anyone please explain this to me? The polygons all have valid geometry but the resulting multipolygon somehow doesn't. The following script:

from shapely.geometry import Polygon, MultiPolygon

polygon1 = Polygon([(0,0), (1,0), (1,1), (0,1), (0,0)])
polygon2 = Polygon([(1,1), (2,1), (2,2), (1,2), (1,1)])
polygon3 = Polygon([(1,0), (2,0), (2,1), (1,1), (1,0)])
polygon_list = [polygon1,polygon2, polygon3]

mpolygon = MultiPolygon(polygon_list)

for item in polygon_list:
print(item.is_valid)
for item in mpolygon:
print(item.is_valid)

print(mpolygon.is_valid)

returns the following:

True
True
True
True
True
True
False

I believe this is causing me problems as I need to intersect a multilinestring with a multipolygon, and the intersection method requires for all the polygon geometries to be valid.

Why are the individual polygons valid while the full multipolygon is not?

It's because polygon1 and polygon3 that you created intersect along an infinite amount of points. Taken here from the Shapely documentation: ...On the right, a valid MultiPolygon with 2 members, and on the right, a MultiPolygon that is invalid because its members touch at an infinite number of points (along a line). Link

To fix this, you need to shift polygon3 so that it will have a maximum of one intersecting point with the other polygons (or none at all). In addition to @15Step's answer, If you want to fix the invalidity, use buffer method. But if polygons are adjacent, you get polygon instead of multipolygon.

mpolygon = mpolygon.buffer(0)
print(mpolygon.is_valid)
print(type(mpolygon))
# OUT:
#   True
#   <class 'shapely.geometry.polygon.Polygon'> If you need multipolygon, you have to convert polygon to multipolygon.

if isinstance(mpolygon, Polygon):
mpolygon = MultiPolygon([mpolygon])
• I need an mpolygon, because I wish to do mpolygon.intersection(multilinestring) where mpolygon has many polygons and multilinestring has many LineStrings which may or may not share vertices – user32882 Oct 9 '18 at 11:04